0

我有这样的课:

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

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

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

但是,这将首先对“项目”表进行查询,这在我的情况下是不必要的。我可以将其更改为

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

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

这不使用关联的附加属性(在本例中为 ":order => :position"),因此如果我想获得与同一示例中完全相同的结果,我将不得不编写:

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

在这里我不再干了,因为我在重复一些已经在模型中定义的东西(“:order”选项)。

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

4

2 回答 2

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

作用域越多、越复杂,这种方法就越有用。

于 2013-08-25T11:19:13.753 回答
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])
于 2013-08-25T11:44:25.953 回答