跟随关联而不加载父对象

时间:2013-08-25 08:55:36

标签: ruby-on-rails ruby-on-rails-2

我有一个这样的课程:

class Project < ActiveRecord::Base
  has_many :versions, :order => :position
end

在控制器操作中,我需要查询项目的版本。我有项目ID。我可以简单地做一个

versions = Project.find(params[:project_id]).versions

但是,这将首先对“projects”表进行查询,这在我的情况下是不必要的。我可以把它改成

versions = Version.find( :conditions => { :project_id => params[:project_id } )

(或使用具有相同结果的动态查找器)

这不使用关联的附加属性(在这种情况下,“:order =&gt;:position”),所以如果我想获得与同一个例子中完全相同的结果,我将拥有写:

versions = Version.find( :conditions => { :project_id => params[:project_id },
                         :order => :position )

在这里,我不再干,因为我正在重复已经在模型中定义的某些内容(“:order”选项)。

有没有办法使用和遵循模型中定义的关联而无需加载父对象?我目前仍在使用Rails 2.3.8。

2 个答案:

答案 0 :(得分:0)

抱歉,我很确定你不能这样做 - 至少不遵循公共的ActiveRecord API。

您可以编写使用内部ActiveRecord API来检查关联选项的扩展程序,但我不建议这样做。

您可以通过范围重用某些条件,但是因为您仍然使用Rails 2.3而无法帮助您。

我认为您最好的选择是手动获取版本实例,就像您在上一个示例中所写的那样:

versions = Version.find( :conditions => { :project_id => params[:project_id },
                         :order => :position )

编辑:你可以在Rails4中做什么:

您可以在模型和关联之间重用和共享范围,如下所示:

class Project < ActiveRecord::Base
  has_many :versions, -> { ordered }
end

class Version
  def self.ordered
    order(:position)
  end
end

versions = Version.find_by(:project_id, params[:project_id]).ordered

范围越多,它们越复杂,这种方法就越有用。

答案 1 :(得分:0)

我建议使用一个default_scope进行排序,另一个范围用于按版本模型中的项目查找版本。

项目

class Project < ActiveRecord::Base
  has_many :versions
end

版本

 class Version < ActiveRecord::Base
   belongs_to :project
   named_scope :order_by_position, {:order => "position"} 
   named_scope :by_project_id, (lambda do |project_id| 
          {:conditions => ['project_id = ?', project_id]}
   end)
 end

然后你可以使用:

versions  = Version.by_project_id(params[:project_id])