困っていたこと
gemのact_as_listsをアイテムの並び替えに使っていたところ、下記のようなエラーが発生してrails db:migrate:resetが妨げられる現象がローカル開発環境で多発していた。(一方、本番デプロイは成功していた。)
$ rails db:migrate
== 20210406073220 CreateItems: migrating ===============================
-- create_table(:items)
-> 0.0123s
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
undefined method `position' for #<Item:0x00007ff2df744198>
Did you mean? position=
実装はこんな感じ。
Gemfile
gem 'acts_as_list'
db/migrate/20220203113520_add_position_to_items.rb
class AddPositionToItems < ActiveRecord::Migration[6.1]
def up
add_column :items, :position, :integer
# 既存のitemにデフォルトの順番番号を入れる
Item.all.each { |i| i.update_column(:position, i.id) }
end
def down
remove_column :items, :position
end
end
position
は後から追加したものなので、create_tableする段階で怒られるのは辛い...。
7年前ですが、Stack overflowにも同じ問題が投稿されていました。が...
回答は1件しかなく、テーブルをcreateするmigrationファイルでpositionを追加したら?と書いてある。
ローカルならそれでもいいが、本番でそれは辛い。
解決!
modelに記述するacts_as_list
に条件分岐を加えました。
app/models/item.rb
class Item < ApplicationRecord
acts_as_list if has_attribute?(:position)
end
参考
- has_attribute?メソッド
これでエラーが出なくなりました!
感謝 to @yukabeoka, @Y_uuu 。