假设我有以下类(class)

class SolarSystem < ActiveRecord::Base
  has_many :planets
end

class Planet < ActiveRecord::Base
  scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
end
Planet的作用域为life_supportingSolarSystem has_many :planets。我想定义我的has_many关系,以便当我向所有关联的solar_system询问planets时,会自动应用life_supporting范围。本质上,我想要solar_system.planets == solar_system.planets.life_supporting
要求
  • 我要做而不是想要更改scope :life_supporting中的Planetdefault_scope where('distance_from_sun > ?', 5).order('diameter ASC')
  • 我也想通过不必添加到SolarSystem来防止重复has_many :planets, :conditions => ['distance_from_sun > ?', 5], :order => 'diameter ASC'

  • 目标
    我想吃点类似的东西has_many :planets, :with_scope => :life_supporting编辑:变通
    正如@phoet所说,使用ActiveRecord可能无法实现默认范围。但是,我发现了两个潜在的解决方法。两者都防止重复。第一个虽然很长,但仍保持明显的可读性和透明性,第二个是帮助程序类型的方法,其输出是显式的。
    class SolarSystem < ActiveRecord::Base
      has_many :planets, :conditions => Planet.life_supporting.where_values,
        :order => Planet.life_supporting.order_values
    end
    
    class Planet < ActiveRecord::Base
      scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
    end
    
    另一个更清洁的解决方案是将以下方法简单地添加到SolarSystem
    def life_supporting_planets
      planets.life_supporting
    end
    
    并在需要使用solar_system.life_supporting_planets的任何地方使用solar_system.planets
    两者均未回答问题,因此如果有人遇到这种情况,我将它们放在此处作为解决方法。

    最佳答案

    在Rails 4中,Associations具有可选的scope参数,该参数接受应用于Relation的lambda(请参阅ActiveRecord::Associations::ClassMethods的文档)

    class SolarSystem < ActiveRecord::Base
      has_many :planets, -> { life_supporting }
    end
    
    class Planet < ActiveRecord::Base
      scope :life_supporting, -> { where('distance_from_sun > ?', 5).order('diameter ASC') }
    end
    

    在Rails 3中,有时可以通过使用where_values来改进where_values_hash的解决方法,该方法可以更好地处理由多个where或哈希定义条件的范围(此处不是这种情况)。

    has_many :planets, conditions: Planet.life_supporting.where_values_hash
    

    关于ruby-on-rails-3 - 默认在Rails has_many关系上使用范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11636541/

    10-11 02:34