仮定
- これは、1人だけでなく多くのユーザー向けのシステムであるため、連絡先レコードとグループレコードで外部キーを使用して所有者を指定する必要があります。
- 連絡先は複数のグループに属することができ、グループには複数の連絡先があるため、これは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関係のテーブルを作成します。2つの外部キーがあります。1つは連絡先用で、もう1つはグループ用です。
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はモデルの名前と一致するため、:のように指定する必要はありません。オーナー。最後に、グループとの多くの関係を持っており、それに属しています。
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テーブルのモデルを作成する必要はありません。
結果
これにより、次のようなことができるようになります。
@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_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
れます。コントローラーアクションには、それを実行するのに十分な情報が含まれています。