我正在为我的学校开发一个项目(不要担心这不会在代码上评分)而且我正在寻找一种干净的方法来遍历ActiveRecord中的关系。
我有一个名为Users,Groups and Assignments的ActiveRecord类。用户和组具有HABTM关系以及组和分配。现在我需要的是一个用户函数get_group(aid),其中“给定一个用户,找到给定一个赋值的组”。
简单的路线是:
def get_group(aid)
group = nil
groups.each { |g| group = g if g.assignment.find(aid).id == aid }
return group
end
是否有更清晰的实现利用了组和赋值之间的HABTM关系而不仅仅是迭代?我还尝试过的一件事是:find()的include选项,如下所示:
def get_group(aid)
user.groups.find(:first,
:include => :assignments,
:conditions => ["assignments.id = ?", aid])
end
但这似乎不起作用。有什么想法吗?
答案 0 :(得分:3)
首先,小心。由于您对两种关系都使用has_and_belongs_to_many
,因此给定的Group
和User
可能会有多个Assignment
。所以我将实现一个返回Group
s。
其次,带有赋值id的方法User#get_group
的名称非常具有误导性,而且不像Ruby那样。
这是一种使用Ruby的Array#&
(交集运算符)获取所有公共组的简洁方法。我为该方法提供了一个更具启发性的名称,并将其放在Group
上,因为它返回Group
个实例。但请注意,它加载的Group
与一个而不是另一个相关:
class Group < ActiveRecord::Base
has_and_belongs_to_many :assignments
has_and_belongs_to_many :users
# Use the array intersection operator to find all groups associated with both the User and Assignment
# instances that were passed in
def self.find_all_by_user_and_assignment(user, assignment)
user.groups & assignment.groups
end
end
然后,如果你真的需要User#get_groups
方法,你可以这样定义:
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
def get_groups(assignment_id)
Group.find_all_by_user_and_assignment(self, Assignment.find(assignment_id))
end
end
虽然我可能会将其命名为User#groups_by_assignment_id
。
我的Assignment
模型很简单:
class Assignment < ActiveRecord::Base
has_and_belongs_to_many :groups
end