前提・実現したいこと
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
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/10/06 08:26 編集