Rails 4 - 为包含的模型添加范围

时间:2014-03-10 04:35:01

标签: ruby-on-rails ruby-on-rails-4

我有这个协会

class Product
  has_many :categorizations
  has_many :categories, through: :categorization

  scope :first_five, lambda { limit(5) }
end

class Category
  has_many :categorizations
  has_many :products, through: :categorization
end

对于每个类别,我希望使用上面定义的first_five范围获得前五个产品

为了最小化数据库请求,我使用includes()

@categories = Category.includes(:products).all

但是如何将范围添加到products?我不想使用default_scope,因为它会影响一切。

我无法在Google上找到它(或者我无法为其获取正确的搜索字词)

由于

3 个答案:

答案 0 :(得分:2)

Rails 4中lambda范围的新语法是:

scope :first_five, -> { limit(5) }

要限制AR查询中的五个产品,您可以执行以下操作:

@categories = Category.includes(:products).merge(Product.first_five).all

merge(Product.first_five)将在限量五种产品上添加left outer join

更新:

上面提到的代码将限制类别。原始问题的可能解决方案可能是在has_many...through模型上添加另一个名为limited_products的{​​{1}}关系:

Category

使用此has_many :limited_products, -> { limit(5) }, through: :products, source: :categorizations 应该会产生将产品限制为Categeory.includes(:limited_products)的预期结果。

根据您的建议,将5选项添加到新添加的关联source: :categorizationslimited_productssource应该是同义词。由于我们定义的关联是忽略class_name选项的has_many...through关联,因此我们应该使用class_name选项而不是:source选项。 :class_name关系中忽略的其他关联选项为has_many...through:primary_key

答案 1 :(得分:2)

@categories = Category.includes(:products).all

它将获取所有类别及其相关产品。此限制不适用于产品。

只是另一种方式。 在Category模型中

has_many :products, through: :categorization, limit: 5

现在你需要加入它,如下所示。

@categories = Category.joins(:products).all

它返回所有类别,并在获取每个category.products时,它将为每个类别返回五个产品。

我知道这不是你要找的答案。但那就是我所拥有的。

替代方式

在类别模型中

has_many :products, through: :categorization

def get_products(limit=5)
  products[0...limit]
end

在控制器中

@categories = Category.joins(:products).all

@categories.each do |category|
  products = category.get_products
  # YOUR CODE GOES HERE
end

每个类别将获得5个产品。

答案 2 :(得分:1)

这将有效

class Category
  has_many :categorizations
  has_many :products, -> { limit(5) },  through: :categorization
end