10

Rails は初めてで、Rails プロジェクトで多対多の関係を設定しようとしています。小さな戦略がありますが、それが正しい方法かどうかはわかりません。

目的: ユーザーのテーブルとグループのテーブルがあります。ユーザーは多くのグループに属することができ、各グループには多くのユーザーが含まれる場合があります。

ストラテジー:

  1. name:string を持つようにユーザーの移行を設定する
  2. 名前:文字列を持つようにグループの移行を設定します
  3. 結合テーブルの移行をセットアップする
  4. has_and_belongs_to_many :groups を持つように User モデルをセットアップします
  5. has_and_belongs_to_many :users を持つようにグループ モデルを設定します。

これは正しい戦略でしょうか?ありがとう!

Railcast の回答の要約: 関心のある方のために、Railcast は has_many :through 関連付けを使用することをお勧めします。これは、上記の戦略にはリレーション固有の情報を追加できないという制限があるためです。

チェックアウト: http://kconrails.com/tag/has_many/

4

1 に答える 1

17

まず、フィールド「名前」を持つユーザーモデルとフィールド「名前」を持つグループモデルがあると仮定します。

users と groups の間にモデルが必要です。これをグループ化と呼びましょう:

rails g model grouping user_name:string group_name:string

グループ化モデル (grouping.rb) では、次のように記述します。

belongs_to :user  
belongs_to :group

ユーザーモデルでは:

has_many :groupings, :dependent => :destroy
has_many :groups, :through => :groupings

グループモデルでは:

has_many :groupings, :dependent => :destroy  
has_many :users, :through => :groupings

ユーザーのプロファイルを編集または更新するには、_form ファイルに次のように記述します。

<div class="field">
    <%= f.label :group_names, "Groups" %>  
    <%= f.text_field :group_names %>  
</div>

最後に、ユーザー クラスは、フォームからの情報をどう処理するかを認識している必要があります。user.rb に挿入します。

  attr_writer :group_names
  after_save :assign_groups

  def group_names
    @group_names || groups.map(&:name).join(' ')
  end

  private

  def assign_groups
    if @group_names
      self.groups = @group_names.split(/\,/).map do |name|
        if name[0..0]==" "
          name=name.strip
        end
        name=name.downcase
        Group.find_or_create_by_name(name)
      end
    end
  end

assign_groups は空白を削除し、すべての単語を小文字にするため、冗長なタグはありません。

これで、ユーザーのプロファイルの表示ファイルでユーザーのグループを表示できます。

<p>Groups:
  <% @user.groups.each do |group|%>
    <%= group.name %>
   <% end %>
</p>

うまくいけば、それは役に立ちます。

于 2012-04-21T18:43:27.230 に答える