質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1084閲覧

rails console上では動くメソッドがコントローラ上では動かない

shinchan_

総合スコア2

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/10/06 06:59

前提・実現したいこと

Trelloのコピーアプリを作成しています。
todoリスト内のカードの順番を入れ替える機能を作成中です。

rails console上では問題なく動いているメソッドがコントローラー内で未定義のメソッドとして認識されることを解決したいです。
以下のメソッドが今回、困っているメソッドになります。
参考にした記事:メソッドの存在を知るきっかけ
参考にした記事:該当のメソッドの継承に関して

rb

1属性名_changed?メソッド

発生している問題・エラーメッセージ

NoMethodError in CardController#update undefined method `order_number_changed?' for #<ActionController::Parameters:0x00007f9bf6f16190> Extracted source (around line #34): 32 33 34 35 36 37 @card = update_card_params byebug replace_order_number(@must_change_card) if @card.order_number_changed? if @card.save redirect_to :root else

該当のソースコード

rb

1class CardController < ApplicationController 2 DEFAULT_ORDER_NUMBER = 0 3 ADD_ORDER_NUMBER = 1 4 5 before_action :find_list, only: :create 6 before_action :set_card, only: %i(show edit update destroy replace_order_number) 7 8 def new 9 @card = Card.new 10 end 11 12 def create 13 @card = Card.new(create_card_params) 14 if @card.save 15 redirect_to :root 16 else 17 render action: :new 18 end 19 end 20 21 def show 22 end 23 24 def edit 25 @lists = List.where(user: current_user) 26 @order_numbers = Card.where(list: params[:list_id]) 27 end 28 29 def update 30 find_change_card 31 initialize_order_number(@must_change_card) 32 @card = update_card_params 33 replace_order_number(@must_change_card) if @card.order_number_changed? 34 if @card.save 35 @must_change_card.save 36 redirect_to :root 37 else 38 render action: :edit 39 end 40 end 41 42 def destroy 43 @card.destroy 44 redirect_to :root 45 end 46 47 private 48 def create_card_params 49 params.require(:card).permit(:title, :memo).merge(list: find_list).merge(order_number: create_order_number) 50 end 51 52 def update_card_params 53 params.require(:card).permit(:title, :memo, :list_id, :order_number) 54 end 55 56 def find_list 57 @list = List.find(params[:list_id]) 58 end 59 60 def set_card 61 @card = Card.find(params[:id]) 62 end 63 64 def create_order_number 65 list = Card.find_by(list_id: params[:list_id]) 66 if list.nil? 67 order_number = ADD_ORDER_NUMBER 68 else 69 order_number = Card.maximum(:order_number) + ADD_ORDER_NUMBER 70 end 71 end 72 73 def find_change_card 74 @must_change_card = Card.find_by(order_number: params[:card][:order_number]) 75 end 76 77 def initialize_order_number(must_change_card) 78 @must_change_card.order_number = DEFAULT_ORDER_NUMBER 79 end 80 81 def replace_order_number(must_change_card) 82 must_change_order_number = @card.order_number_was 83 @must_change_card.order_number = must_change_order_number 84 @must_change_card 85 end 86end

試したこと

属性名_changed?メソッドの仕様を確認しました。
=> DB登録前の変更のみ検知することを確認しました。

irb

1irb(main):001:0> @card1 = Card.find(1) 2 (0.1ms) begin transaction 3 Card Load (1.0ms) SELECT "cards".* FROM "cards" WHERE "cards"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] 4=> #<Card id: 1, title: "ff", memo: "", list_id: 1, created_at: "2021-10-06 05:28:52", updated_at: "2021-10-06 05:42:26", order_number: 1> 5 6irb(main):002:0> @card1.order_number = 2 7=> 2 8 9irb(main):003:0> @card1.order_number_changed? 10=> true 11 12irb(main):004:0> @card1.save 13 (0.1ms) SAVEPOINT active_record_1 14 List Load (0.5ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] 15 Card Update (0.5ms) UPDATE "cards" SET "updated_at" = ?, "order_number" = ? WHERE "cards"."id" = ? [["updated_at", "2021-10-06 06:45:18.203773"], ["order_number", 2], ["id", 1]] 16 (0.1ms) RELEASE SAVEPOINT active_record_1 17=> true 18 19irb(main):005:0> @card1.order_number_changed? 20=> false

今回のメソッドのクラス継承に関しても調べ、ActiveRecord::Baseを継承していれば使用可能と認識しております。
以下の記事で確認しました。
参考にした記事:メソッドの存在を知るきっかけ

コントローラーのクラス継承を以下の記事で確認しました。
参考にした記事:該当のメソッドの継承に関して
=> メソッドとアクションの下の方に書いてあります。

原因がお分かりの方、ご教授お願い致します。

補足情報(FW/ツールのバージョンなど)

macOS, rails6.0.4, ruby2.7.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

エラーメッセージのとおりです。

@cardに入れたupdate_card_paramsは、paramsから抽出したパラメーター値(ActionController::Parameters)であって、モデルではありません

投稿2021/10/06 07:03

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shinchan_

2021/10/06 08:26 編集

ご回答、ありがとうございます。 ```rb def update find_change_card initialize_order_number(@must_change_card) @card.order_number = params[:card][:order_number] replace_order_number(@must_change_card) if @card.order_number_changed? if @card.update(update_card_params) byebug @must_change_card.update(order_number: @must_change_order_number) redirect_to :root else render action: :edit end end ``` ご回答のおかげで先程のエラーから抜け出し、また別のエラーと格闘できています。 助かりました。 また、よろしければ、ご回答お願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問