3

为模特追随我的头

  1. 用户有许多联系人类别(家人/朋友)
  2. 一个联系人类别有多个联系人
  3. 一位联系人可以属于一个或多个联系人类别。

我最终得到了关注,但我仍然相信,一定有更好的解决方案。

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 
4

2 回答 2

6

假设

  • 这是一个适用于许多用户的系统,而不仅仅是一个用户,因此您需要使用外键在联系人和组记录上指定所有者。
  • 一个Contact可以属于多个Group,一个Group有多个contact,所以这是has_and_belongs_to_many关系。

迁移

创建用户表:

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

接触模型。一个联系人属于一个所有者,我们正在为所有者关系使用“用户”模型。此外,Contact 指的是另一个用户(或属于,Rails 用语,这在这种情况下有点令人困惑),但是 :user 匹配模型的名称,所以我们不需要像我们那样指定:所有者。最后,与 Groups 的 has 和属于 many 关系。

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 表创建模型,因为我们不会直接访问它,而只会通过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 评论的回应,该评论询问视图将联系人添加到组中的外观。

实际上有很多不同的方法可以实现这一点,但总体思路是您需要将联系人 ID 和组 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_idand传递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_idand传递group_id给控制器​​动作,然后控制器就有足够的信息来做这件事。

于 2012-05-11T16:39:49.910 回答
2

You can use has_many :through Association

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

this will work.

于 2012-05-11T08:57:52.480 回答