摔跤我的头脑模型
我最终会跟随,但我仍然相信,必须有更好的解决方案。
class User < ActiveRecord::Base
has_many :contact_groups
def get_all_contacts
self.contact_groups.each do |group|
contacts << group.users
end
end
class ContactGroup < ActiveRecord::Base
has_and_belongs_to_many :users
end
答案 0 :(得分:6)
创建用户表:
class CreateUsers < ActiveRecords::Migrations
def change
create_table :users do |t|
t.text :username
end
end
end
创建联系人表格。具有联系人所拥有的用户的外键以及联系人所引用的用户。
class CreateContacts < ActiveRecord::Migrations
def change
create_table :contacts do |t|
t.references :owner
t.references :user
end
end
end
创建组表。还有该组所属用户的外键。
class CreateGroups < ActiveRecord::Migrations
def change
create_table :groups do |t|
t.references :owner
t.text :name
end
end
end
为联系人和群组之间的has_and_belongs_to_many关系创建表格。有两个外键;一个用于联系人,另一个用于组。
class CreateContactsGroups < ActiveRecord::Migrations
def change
create_table :contacts_groups do |t|
t.references :contact
t.references :group
end
end
end
用户模型。用户具有多个联系人,联系人表上与用户联系的外键是'owner_id'列。群组也是如此。
class User
has_many :contacts, :foreign_key => 'owner_id'
has_many :groups, :foreign_key => 'owner_id'
end
联系模式。联系人属于所有者,我们使用“用户”模型作为所有者关系。此外,联系人指的是另一个用户(或属于Rails用语,在这种情况下有点令人困惑),但是:用户匹配模型的名称,因此我们不需要像以下那样指定:所有者。最后,拥有并属于与群体的许多关系。
class Contact
belongs_to :owner, :class_name => 'User'
belongs_to :user
has_and_belongs_to_many :groups
end
集团模式。一个群组属于所有者,拥有并属于许多联系人。
class Group
belongs_to :owner, :class_name => 'User'
has_and_belongs_to_many :contacts
end
我们不需要为contacts_groups表创建一个Model,因为我们不会直接访问它,而只会通过Contact或Group访问它。
这将允许您执行以下操作:
@user.contacts # all of the user's contacts
@user.groups # all of the user's groups
@user.groups.find(id).contacts # all the contacts in a group
@user.contacts.find(id).groups # all of the groups that a contact belongs to
这是对@benrmatthews评论的回应,询问将联系人添加到群组时的观点是什么。
实际上有很多种方法可以实现这一点,但一般的想法是你需要将Contact id和Group id传递给一个控制器动作,然后在contact_groups表中创建一个条目来指示该联系人已被添加到该组。
您的路线可能如下所示:
resources :contact_groups, only: [:create]
然后你会有一个看起来像这样的控制器:
class ContactGroupsController < ApplicationController
def create
@contact = Contact.find(params[:contact_id])
@group = Group.find(params[:group_id])
@contact.groups << @group
end
end
现在您只需要将contact_id
和group_id
传递给控制器操作的表单。这就是看起来的样子:
# This is for adding the contact to a group
form_tag contact_groups_path do
hidden_field_tag :contact_id, @contact.id
select_tag :group_id, options_from_collection_for_select(Group.all, :id, :name)
submit_tag "Add to Group"
end
这将创建一个带有隐藏字段的表单,其中包含contact_id
和一个将显示组名列表的选择字段。提交此表单后,它会将contact_id
和group_id
传递给控制器操作,然后控制器操作就会有足够的信息来执行此操作。
答案 1 :(得分:2)
您可以使用has_many:通过关联
class User
has_many :contacts
has_many :contact_groups, :through => :contacts
end
class Contact
belongs_to :user
has_many :contact_groups
end
class ContactGroup
belongs_to :contacts
end
这将有效。