如何加入与Active Record中的作用域的has_many关联?

时间:2011-09-19 17:53:22

标签: ruby-on-rails activerecord scope associations

这是我的关联和范围设置:

has_many    :owned_products

has_many    :owned_lessons, :through => :owned_products, :source => :lesson, :conditions => "owned_products.product_type = 'Lesson'"

scope :active_purchase_scope, lambda {
    where('owned_products.created_at' => (Date.today - CONFIG['downloads']['time_window'].days)..(Date.today)).order('owned_products.created_at DESC')
}

def active_lessons 
    owned_lessons.active_purchase_scope
end

这是我得到的错误:

ruby-1.8.7-p334 :005 > User.find_by_username('joeblow').active_lessons
NoMethodError: undefined method `active_purchase_scope' for #<User:0x1051a26c8>

1 个答案:

答案 0 :(得分:4)

可以将scope视为类方法,可以将association视为实例方法。在您的代码示例中,owned_lessons方法返回一个数组对象。您不能在数组对象(或User对象)上调用active_purchase_scope,因为范围只能在Model类上调用(即在您的情况下User.active_purchase_scope

您可以通过在Lesson型号

上添加范围来解决此问题
class Lesson
  has_many    :owned_products

  scope :active_purchase_scope, lambda {
    include(::owned_products).where('owned_products.created_at' => 
          (Date.today - CONFIG['downloads']['time_window'].days)..(Date.today)).
            order('owned_products.created_at DESC')
  }

end

并按如下方式重写User类:

class User

  has_many    :owned_products

  has_many    :owned_lessons, :through => :owned_products, :source => :lesson, 
                 :conditions => "owned_products.product_type = 'Lesson'"


  def active_lessons 
    owned_lessons.active_purchase_scope
  end

end

owned_lessons返回Lesson模型上的匿名范围,因此我们可以使用同一模型中的范围active_purchase_scope对其进行链接。