3

次のモデルに頭を悩ませる

  1. ユーザーには多くの連絡先カテゴリ(家族/友人)があります
  2. 1つの連絡先カテゴリには多くの連絡先があります
  3. 1つの連絡先は、1つ以上の連絡先カテゴリに含めることができます。

私は最終的に次のようになりますが、それでも私は、ここにもっと良い解決策があるに違いないと信じています。

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

仮定

  • これは、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_idgroup_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れます。コントローラーアクションには、それを実行するのに十分な情報が含まれています。

于 2012-05-11T16:39:49.910 に答える
2

has_many:throughAssociationを使用できます

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

これは機能します。

于 2012-05-11T08:57:52.480 に答える