1

只是学习轨道...

我有以下型号:

class TimeSlot < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::
   has_and_belongs_to_many :time_slots
end

我还有一个模型可以加入两者:

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

在控制台中,我创建了一个用户对象,并且我想将它与 TimeSlot 相关联。我有一个变量ts,它是一个 TimeSlot 对象,u它是一个用户对象。两者都已存在于数据库中。当我这样做时ts.users << u,我收到一条错误消息:“ActiveRecord::StatementInvalid: SQLite3::ConstraintException: time_slots_users.created_at may not be NULL: INSERT INTO "time_slots_users" ("time_slot_id", "user_id") VALUES (1, 1)。

为什么 created_at 会为空?不是在创建 TimeSlotsUsers 中的记录时自动创建的吗?我是否需要改用 has-many through 关系?

4

2 回答 2

2

如果您希望将 user_id 和 timeslot_id 以外的任何信息作为关系的一部分,则连接模型是一个很好的模式。例如,如果你有groups并且users你有一个多对多的关系,但有时用户是一个admin组的一个,你可以把is_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

我不同意其他主张在连接表上没有主键的答案之一。
例如,当您想使用 REST API 删除或编辑该关系时,拥有该关系的唯一 ID 很重要。是否有updated_atcreated_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 回答