Use a scope by default on a Rails has_many relationship

前端 未结 3 986
难免孤独
难免孤独 2021-01-30 05:13

Let\'s say I have the following classes

class SolarSystem < ActiveRecord::Base
  has_many :planets
end

class Planet < ActiveRecord::Base
  scope :life_supp         


        
相关标签:
3条回答
  • 2021-01-30 05:22

    In Rails 5, the following code works fine...

      class Order 
        scope :paid, -> { where status: %w[paid refunded] }
      end 
    
      class Store 
        has_many :paid_orders, -> { paid }, class_name: 'Order'
      end 
    
    0 讨论(0)
  • 2021-01-30 05:45

    In Rails 4, Associations have an optional scope parameter that accepts a lambda that is applied to the Relation (cf. the doc for 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
    

    In Rails 3, the where_values workaround can sometimes be improved by using where_values_hash that handles better scopes where conditions are defined by multiple where or by a hash (not the case here).

    has_many :planets, conditions: Planet.life_supporting.where_values_hash
    
    0 讨论(0)
  • 2021-01-30 05:48

    i just had a deep dive into ActiveRecord and it does not look like if this can be achieved with the current implementation of has_many. you can pass a block to :conditions but this is limited to returning a hash of conditions, not any kind of arel stuff.

    a really simple and transparent way to achieve what you want (what i think you are trying to do) is to apply the scope at runtime:

      # foo.rb
      def bars
        super.baz
      end
    

    this is far from what you are asking for, but it might just work ;)

    0 讨论(0)
提交回复
热议问题