遍历ActiveRecord上的HABTM关系

时间:2008-10-02 04:41:56

标签: ruby-on-rails activerecord

我正在为我的学校开发一个项目(不要担心这不会在代码上评分)而且我正在寻找一种干净的方法来遍历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

但这似乎不起作用。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

首先,小心。由于您对两种关系都使用has_and_belongs_to_many,因此给定的GroupUser可能会有多个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