1

has_many 関係の間にいくつかの追加のプロパティを追加することを検討していました。

たとえば、Users テーブルと Group テーブルがあります。ユーザーは :through has_many 関係を介してグループに参加できます。そのグループ内のユーザーの「ロール」のプロパティを追加したいと考えています。

create_table "groupization", :force => true do |t|
    t.integer  "user_id"
    t.integer  "group_id"
    t.string  "role"
    t.datetime "created_at",                     :null => false
    t.datetime "updated_at",                     :null => false
  end

どうすればロール属性にアクセスできるのだろうと思っていました。私は次のようなことを考えていました:

user.groups[0].role 

それは正しいアプローチですか?構文が間違っていることはわかっています (試してみました)。正しい構文はどのようなものでしょうか? ありがとう!

4

4 に答える 4

3

これを行うエレガントな方法はないと思います。次のようなものです。

user.groupizations.find_by_group_id(user.groups[0].id).role

で提供したサンプル コードは[0]現実的な使用法とは思えないため、実際に にアクセスする方法を示していただければrole、よりクリーンな方法があるかもしれません。

これはここで議論されました。

于 2012-05-13T00:53:45.287 に答える
2

これに対する最善のアプローチは、結合モデルを使用してから、グループにメソッドを委任/プロキシすることです。例:

class User < ActiveRecord::Base
  has_many :memberships, :include => :group, :dependent => :delete_all
  has_many :groups, :through => :memberships
end

class Group < ActiveRecord::Base
   has_many :memberships, :include => user, :dependent => :delete_all
   has_many :users, :through => :memberships
end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group

  def group_name
    group && group.name
  end

  def user_name
    user && user.name
  end
end

次に、ユーザーのグループをビューに表示する場合:

<ul>
<% @user.memberships.each do |membership| %>
  <li><%= membership.group_name %> (<%= membership.role %>)</li>
<% end %>
</ul>

グループのユーザーについても同様です。

<ul>
<% @group.memberships.each do |membership| %>
  <li><%= membership.user_name %> (<%= membership.role %>)</li>
<% end %>
</ul>

この方法では、ユーザー、グループ、およびメンバーシップごとに1つずつ、合計3つのクエリのみが実行されます。

于 2012-05-13T12:53:08.597 に答える
2

User モデルには、次のようなものがあります。

class User < ActiveRecord::Base
  has_many :groupizations
  has_many :groups, :through => :groupizations
end

コンソールでこのようにhas_many関係を介してロール情報にアクセスします。groupizations

foo = User.first
bar = foo.groupizations.first
bar.role

最初のユーザーにグループ化があると仮定します。

特定のユーザー/グループ関係を取得するには、次のようにします。

Groupizations.where("group_id = ? and user_id = ?", group.id, user.id)

そこから、探していた役割を取得できます。

于 2012-05-13T12:32:56.903 に答える
1

あなたが何を探しているのか正確には明らかではないので、何が起こっているのかをより明確にするために、コンソール出力の別の例を投げ出します。ただし、ポイントは、ユーザーの役割だけを取得するには、どのユーザーのグループを意味するかを指定する必要があるということです(@BuckDoyleで示されているように、彼は最初のグループを選択して例をミラーリングするだけです) . ユーザーのすべてのロールのリストを取得するには、ユーザーのグループ化を繰り返す必要があります。

1.9.3-p194 :050 > User.find_by_name("Homer").groupizations.each {|groupization| 
                 puts groupization.group.org + ': ' + groupization.role}

User Load (2.8ms)  SELECT "users".* FROM "users" WHERE "users"."name" = 'Homer' LIMIT 1
Groupization Load (1.5ms)  SELECT "groupizations".* FROM "groupizations" WHERE 
"groupizations"."user_id" = 2

Group Load (1.9ms)  SELECT "groups".* FROM "groups" WHERE "groups"."id" = 1 
LIMIT 1

The Movementarians: cult follower

Group Load (1.4ms)  SELECT "groups".* FROM "groups" WHERE "groups"."id" = 2 
LIMIT 1

Nuclear Plant: employee

最後に 1 つ (ちょっと些細なことですが) 「グループ化」は確かに機能しますが、追加する属性が「役割」だけである場合は、関係モデルをより具体的な名前 (「メンバーシップ」など) にすると、実用的な利点があります。少なくとも私の経験では、関係が少し明確になります。

于 2012-05-13T12:10:35.143 に答える