概要
Rails5で、1からアプリを作り始めたときに躓いた。
Rail5からbelong_toのデフォルト値が下記記事の通り変わったらしい。
Rails5からbelongs_to関連はデフォルトでrequired: trueになる
具体的な例
EventモデルとItemモデルがあり、Eventは複数のItemを保有するとしたとする。
モデルの記述は以下の通り
db/schema.rb
create_table "events", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "items", force: :cascade do |t|
t.integer "event_id"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
app/models/event.rb
class Event < ApplicationRecord
has_many :items
end
app/models/item.rb
class Item < ApplicationRecord
belongs_to :event
end
このとき、以下の文はエラーになる。
$ rails c
> item = Item.new(name: 'test name')
=> #<Item id: nil, event_id: nil, name: "test name", created_at: nil, updated_at: nil>
> item.save
(0.2ms) BEGIN
(0.4ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Event must exist
対応策
Rail5からbelongs_toのデフォルトが関連先の値を検査するようになった。Rails4と同様に関連先を検査しないようにするには、belongs_toにoptional: trueを付与すれば良い。
app/models/item.rb
class Item < ApplicationRecord
belongs_to :event, optional: true
end
> item.save
(0.3ms) BEGIN
SQL (0.5ms) INSERT INTO "items" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["name", "test name"], ["created_at", 2016-12-24 13:31:36 UTC], ["updated_at", 2016-12-24 13:31:36 UTC]]
(1.7ms) COMMIT
=> true
以上