【问题标题】:Traversing HABTM relationships on ActiveRecord在 ActiveRecord 上遍历 HABTM 关系
【发布时间】:2008-10-02 04:41:56
【问题描述】:

我正在为我的学校在 Rails 上做一个项目(不用担心这不会在代码上评分),我正在寻找一种干净的方式来遍历 ActiveRecord 中的关系。

我有 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

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

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    首先,要小心。由于您对这两种关系都使用了has_and_belongs_to_many,因此对于给定的UserAssignment,可能有不止一个Group。所以我要实现一个返回Groups数组的方法。

    其次,采用分配 id 的方法 User#get_group 的名称非常具有误导性,而且不像 Ruby。

    这是使用 Ruby 的 Array#&(交集运算符)获取所有公共组的简洁方法。我给该方法取了一个更具启发性的名称,并将其放在Group 上,因为它返回Group 实例。但是请注意,它会加载与一个相关但与另一个无关的Groups:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多