在has_many关系中使用时访问连接表中的额外属性

时间:2012-05-13 00:09:26

标签: ruby-on-rails attributes has-many jointable

我正在考虑在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 个答案:

答案 0 :(得分:3)

我认为没有一种优雅的方法可以做到这一点,就像这样:

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

您使用[0]提供的示例代码似乎不太符合实际用途,因此,如果您向我们展示了您实际想要访问role的方式,那么可能会有更简洁的方法

讨论了here

答案 1 :(得分:2)

在您的用户模型中,您将拥有以下内容:

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)

然后从那里你可以得到你正在寻找的角色。

答案 2 :(得分: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>

这种方式只需要三个查询 - 每个查询分别用于用户,组和成员资格。

答案 3 :(得分: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

最后一个想法(一种微不足道的)“分组”肯定有效,但如果“角色”是你要添加的唯一属性,更具体地命名关系模型(比如说“会员资格”)具有实际的好处因为它使关系更清晰,至少在我的经验中。