我是编程新手,很难确定我需要的模型关联。我已经有两个表:组织和具有1:多关系的用户,因为组织有多个用户/成员。并非所有用户都是组织的成员,但这不是问题。
# In the organization model:
has_many :users
# In the user model:
belongs_to :organization, inverse_of: :users
# In the users migration file:
t.references :organization, index: true, foreign_key: true
我需要使用主持人功能对其进行扩展:用户可以是多个组织的主持人,组织可以有多个用户作为主持人。因此,用户和组织模型之间存在两种不同的原因(用户作为组织成员,用户作为组织的主持人;在成为主持人之前无需成员)。
我读了here关于创建关联的两种不同方法,即has_many :through
或has_and_belongs_to_many
。
最简单的经验法则是你应该设置一个has_many :如果你需要使用关系模型,通过关系 作为一个独立的实体。如果你不需要做任何事情 关系模型,设置一个可能更简单 has_and_belongs_to_many关系(虽然你需要记住 在数据库中创建连接表)。 你应该使用has_many:through如果你需要验证,回调, 或连接模型上的额外属性。
我不确定“如果你需要将关系模型作为一个独立的实体”,那意味着什么。在我的用例中,主持人将拥有其他权利。我相信,该协会将以两种方式使用:1)显示组织的主持人,并显示用户是主持人的组织; 2)查看用户是否拥有版主权限以允许他获得这些权利。所以我不相信我需要验证(组织本身可以选择用户作为主持人)或额外的属性。我不确定回调(不确切知道它们是什么)。
简而言之,在我的用例中,两种关联形式中哪一种是最好的关联?
答案 0 :(得分:2)
当人们问:
habtm
- 只有一个联接表,例如两个ID hm:t
- 包含有关联接关系的元数据的联接表,例如,两个ID和其他数据,如时间,计数等。答案 1 :(得分:2)
“如果您需要将关系模型作为独立实体使用”意味着您将能够像任何其他ActiveRecord模型一样操作关系模型,即您可以创建,保存,销毁等记录或分配各种类型关系的属性。
例如,假设用户可能与组织有不同类型的关系(例如主持人,员工,股东等)。使用:through关联,您将拥有:
class Relationship < ActiveRecord::Base
belongs_to :user
belongs_to :organization
end
class User < ActiveRecord::Base
has_many :organizations, through: relationships
end
class Organization < ActiveRecord::Base
has_many :users, through: relationships
end
# schema.rb
ActiveRecord::Schema.define(:version => 20150511223747) do
# . . . .
create_table "relationships", :force => true do |t|
t.string "relationship_type"
t.integer "user_id"
t.integer "organization_id"
t.datetime "created_at"
t.datetime "updated_at"
end
end
# things you can do:
org = Organization.first
moderators_or_employees = org.users.where("relationship_type = 'moderator' OR relationship_type = 'employee'")
new_moderators = org.users.where("relationship_type = 'moderator' AND DATE(relationships.created_at) > '2015-01-01'")
这些是您无法使用has_and_belongs_to_many关联执行的操作,因为您无法查询关系类型或created_at。由于这些限制,我经常发现:通过关系,虽然有点复杂,但给你更多的灵活性。