1

レールを学ぶだけ...

私は次のモデルを持っています:

class TimeSlot < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::
   has_and_belongs_to_many :time_slots
end

2つを結合するモデルもあります。

class TimeSlotsUsers < ActiveRecord::Base
  attr_accessible :time_slot_id, :user_id
end

コンソールで、ユーザーオブジェクトを作成し、それをTimeSlotに関連付けたいと思います。tsTimeSlotオブジェクトであり、ユーザーオブジェクトである変数がありuます。両方ともデータベースにすでに存在します。するとts.users << u、「ActiveRecord :: StatementInvalid:SQLite3 :: ConstraintException:time_slots_users.created_atはNULLではない可能性があります:INSERT INTO "time_slots_users"( "time_slot_id"、 "user_id")VALUES(1、1)」というエラーが表示されます。

なぜcreated_atがnullになるのでしょうか。TimeSlotsUsersのレコードが作成されるときに、自動的に作成されませんか?代わりに、has-many through関係を使用する必要がありますか?

4

2 に答える 2

2

リレーションシップの一部としてuser_idとtimeslot_id以外の情報が必要な場合は、結合モデルが適したパターンです。たとえば、多対多の関係があり、ユーザーがグループに属している場合は、その属性を結合モデルに配置できgroupsます。usersadminis_admin

結合モデルを維持するために、より良いRailsパターンは次のとおりです...

class TimeSlot < ActiveRecord::Base
  has_many :time_slot_users
  has_many :users, through: :time_slot_users
end

class User < ActiveRecord::Base
  has_many :time_slot_users
  has_many :time_slots, through: :time_slot_users
end

class TimeSlotsUsers < ActiveRecord::Base
  belongs_to :users
  belongs_to :time_slots
end

結合テーブルに主キーがないことを主張する他の回答の1つに同意しません。
たとえば、REST APIを使用してその関係を削除または編集する場合、関係の一意のIDを持つことが重要です。updated_atまたはを持っているかどうcreated_atかは、それらが問題のドメインで有用なデータであるかどうかによって異なります。たとえば、ユーザーがいつグループに追加されたか(または追加されなかったか)を知ることは有用な情報かもしれません。

データの整合性を確保するために、(user_id、time_slot_id)の結合テーブルに一意のインデックスを設定することが重要です。Railsモデルは、99.999%のインスタンスで一意性を確実に検証できますが、100%の時間では検証できません。

于 2013-03-21T11:18:15.300 に答える
1

habtm関係の結合テーブルには列を含めるべきではありませんcreated_atupdated_at。また、結合モデルは必要ありません。

結合テーブルを使用して何かを実行したり、属性を追加したりする場合は、に変更する必要がありますhas_many :through

于 2013-03-21T07:45:05.107 に答える