LoginSignup
81
50

More than 5 years have passed since last update.

(個人メモ)Rails5で関連を定義した時はbelongs_toに気をつける

Last updated at Posted at 2016-12-24

概要

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

以上

81
50
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
81
50