假设
- 这是一个面向多个用户的系统,因此您需要使用外键在联系人和组记录上指定所有者。
- 一个联系人可以属于多个组,一个组可以有多个联系人,因此这是一种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
创建Groups表。同时为所属用户创建一个外键。
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 术语中属于,这在这种情况下有点混乱),但是 :user 匹配模型的名称,因此我们不需要像对 :owner 做的那样指定它。最后,与组之间存在多对多的关系。
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
@user.groups
@user.groups.find(id).contacts
@user.contacts.find(id).groups
将联系人添加到分组
@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_id
和
group_id
传递给控制器操作。下面是示例代码:
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
到控制器操作中,然后该操作将具有足够的信息来执行其任务。