关于ruby on rails 3:Has_many,通过关联

 2022-02-12 

Has_many, through association

警告:Total Rails Newb (TRN)。这应该是一个非常基本的问题,所以我希望有人能抽出几分钟来帮助阐明一些问题。

假设我有以下模型:用户、组和成员
一个用户可以有很多组(比如说朋友、家人等)
一个组可以有许多成员,即其他用户。

我将如何构建它?

最初我尝试过这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class User < ActiveRecord::Base
  has_many :groups
  has_many :groups, :through => :members
end

class Groups < ActiveRecord::Base
  has_many :users, :through => :members
  belongs_to :user
end

class Member < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end

但是这给了我一个用户错误所以我改变了

1
has_many :groups, :through => :members

1
has_many :memberships, :through => :members, :source => :groups

当我尝试做时,仍然收到关于缺少关联的错误

1
2
group = Group.new
group.user.new

这将很有用:http://railscasts.com/episodes/47-two-many-to-many

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class User < ActiveRecord::Base
  has_many :members
  has_many :groups, :through => :members
  has_many :groups_as_owner, :class_name =>"Group"
end

class Groups < ActiveRecord::Base
  has_many :members
  has_many :users, :through => :members
  belongs_to :owner, :class_name =>"User", :foreign_key => :user_id
end

class Member < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end


基本上 has_many-through 关联是 n:m 关联(连接表),它(应该)具有更多属性,而不仅仅是连接记录 id 的 id...

所以你有一个表 Groups(有一个 id),一个表 Users(有一个 id)和一个表 Members(没有 id,但是 user_id 和 group_id)

基本上,您所做的几乎是正确的,只需考虑您如何从用户访问组,反之亦然....

用户首先会查找其成员信息,并通过该成员信息访问组信息......反之亦然,对于一个组

所以你先设置

1
has_many :members

然后调用

1
has_many :groups, :through => :members

你只需要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class User < ActiveRecord::Base
  has_many :members
  has_many :groups, :through => :members
end

class Groups < ActiveRecord::Base
  has_many :members
  has_many :users, :through => :members
end

class Member < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end

你上面的代码中还有另一个错误

你可能想使用

1
user = group.users.new

而不是

1
user = group.user.new


试试这个结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class User < ActiveRecord::Base
  has_many :members
  has_many :groups, :through => :members
end

class Groups < ActiveRecord::Base
  has_many :members
  has_many :users, :through => :members
end

class Member < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end

另外看看has_and_belongs_to_many,如果你不需要使用class Member,那么你应该使用has_and_belongs_to_many。在这种情况下不要忘记在数据库中创建连接表