获取类别和子类别的所有产品(rails、awesome_nested_set)
正在开发一个电子商务应用程序,我试图解决以下问题: 我通过 Awesome_nested_set 插件实现了我的类别。 如果我通过选择一个类别列出我的文章,一切正常,但对于某些链接,我想显示一个类别的所有产品及其子类别的产品。
这是仅适用于一个类别的控制器代码:
# products_controller.rb
def index
if params[:category]
@category = Category.find(params[:category])
#@products = @category.product_list
@products = @category.products
else
@category = false
@products = Product.scoped
end
@products = @products.where("title like ?", "%" + params[:title] + "%") if params[:title]
@products = @products.order("created_at).page(params[:page]).per( params[:per_page] ? params[:per_page] : 25)
@categories = Category.all
end
我注释掉的行是我自己在类别模型中编写的一个辅助方法,该方法以数组形式返回该类别及其子类别的所有产品。
它的定义如下:
# app/models/category.rb
def product_list
self_and_ancestors.to_a.collect! { |x| x.products }
end
现在,当我取消注释这一行并尝试选择一个类别时,我的产品控制器代码会因错误而中断,例如
undefined method `order' for #<Array:0x1887c2c>
或
undefined method `page' for #<Array:0x1887c2c>
因为我正在使用排序和分页,并且它无法再对数组进行排序。
有什么想法如何获取控制器中 ActiveRecord Relation 元素中的所有产品吗? 谢谢
更新,
所以,当我使用以下内容:
class Category < ActiveRecord::Base
acts_as_nested_set
attr_accessible :name, :description, :lft, :rgt, :parent_id
has_many :categorizations
has_many :products, :through => :categorizations
attr_accessor :product_list
def branch_ids
self_and_descendants.map(&:id).uniq
end
def all_products
Product.find(:all, :conditions => { :category_id => branch_ids } )
end
end
并向控制器询问@category.all_products
时,我收到以下错误:
Mysql::Error: Unknown column 'products.category_id' in 'where clause': SELECT `products`.* FROM `products` WHERE `products`.`category_id` IN (6, 8, 9)
如何获得具有此星座的所有产品?
更新2
好的,我要开始赏金了。
如果我尝试:
def all_products Categorization.find(:all, :conditions => { :category_id =>branch_ids } ) 我再次
得到 undefined method
order' for #` 我需要知道如何将 Many_to_many 关系的所有产品作为 ActiveRecord 关系获取。
更新3
我把相关代码放在要点中 https://gist.github.com/1211231
having an e-commerce application under development i am trying to get my head around the following problem:
I have my categories realized through the awesome_nested_set plugin.
If I list my articles through selecting one category everything works fine, but for some links I want to show all the products of one category and the products of its child categories.
here is the controller code that works fine with only one category:
# products_controller.rb
def index
if params[:category]
@category = Category.find(params[:category])
#@products = @category.product_list
@products = @category.products
else
@category = false
@products = Product.scoped
end
@products = @products.where("title like ?", "%" + params[:title] + "%") if params[:title]
@products = @products.order("created_at).page(params[:page]).per( params[:per_page] ? params[:per_page] : 25)
@categories = Category.all
end
The line I commented out is a helper method I wrote myself in the category model which returns all products of the category and its child categories in an array.
It is defined as followed:
# app/models/category.rb
def product_list
self_and_ancestors.to_a.collect! { |x| x.products }
end
Now when I uncomment this line and try to select one category my products controller code breaks with errors like
undefined method `order' for #<Array:0x1887c2c>
or
undefined method `page' for #<Array:0x1887c2c>
because I am using ordering and pagination and it can't order the arary anymore.
Any ideas how to get all the products in an ActiveRecord Relation element in my controller?
thanks
UPDATE
so, when I use the following:
class Category < ActiveRecord::Base
acts_as_nested_set
attr_accessible :name, :description, :lft, :rgt, :parent_id
has_many :categorizations
has_many :products, :through => :categorizations
attr_accessor :product_list
def branch_ids
self_and_descendants.map(&:id).uniq
end
def all_products
Product.find(:all, :conditions => { :category_id => branch_ids } )
end
end
and ask the controller for @category.all_products
i get the following error:
Mysql::Error: Unknown column 'products.category_id' in 'where clause': SELECT `products`.* FROM `products` WHERE `products`.`category_id` IN (6, 8, 9)
How would I get all products with this constellation?
UPDATE 2
Ok, so I am going to start a bounty.
If I try:
def all_products
Categorization.find(:all, :conditions => { :category_id => branch_ids } )
end
I get again undefined method
order' for #`
I need to know how I can get all the products of a many_to_many relation as an ActiveRecord relation.
UPDATE 3
I put the relevant code in a gist
https://gist.github.com/1211231
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Awesome_nested_set 的关键是在 lft 列 中使用范围。
这是一个代码示例,说明我如何通过直接关联(类别 has_many 文章)执行此操作,
然后在控制器中的某个位置,
它将找到苹果、橙子、香蕉等类别下的所有文章。
您应该通过加入分类来适应这个想法(但是您确定这里需要多对多关系吗?)
无论如何,我会尝试这个:
如果有任何问题,请告诉我
The key with awesome_nested_set is to use a range in the lft column.
Here's a code sample of how I do it with a direct association (category has_many articles)
Then somewhere in a controller
that will find all articles under the categories apples, oranges, bananas, etc etc.
You should adapt that idea with a join on categorizations (but are you sure you need a many to many relationship here?)
Anyway I would try this :
Let me know if there's any gotcha
有多种方法可以改进您的代码,但是如果您正在寻找属于某个类别的所有产品以及该类别的子代(后代),那么为什么您不会这样做:
我做了一些假设在这里,但我希望你能明白。
There are a several ways you could improve your code, but if you're looking for all products that belong to a category and children (descendants) of the category then why you won't do it like this:
I've done some assumptions here, but I hope you get the idea.
扩展 charlysisto 的答案,当您处理
has_and_belongs_to_many
类别时,您很快就会发现蛮力透视相当慢......您需要某种“中间件”来使其更快。 ..socjopata 的答案给出了如何改进这一点的好方法。 定义
因此,您可以使用
category.rb
文件(模型)中的。然后,例如,在您的控制器中(例如分页):
最后,在您看来,您将需要一些“技术”才能进行分页。您将在
@prodcats
上分页,而不是@products
...这种方法更快,在处理
many_to_many
时,虽然不是100%政治正确,但我必须承认。Extending charlysisto 's answer, when you are dealing with
has_and_belongs_to_many
categories, you will soon find out that the brute force perspective is quite slow... You need some kind of "middleware" to make it faster...socjopata 's answer gives a good approach of how to improve this. So, you use the definition
in your
category.rb
file (model).Then, for example, in your controller (example with pagination):
Finally, in your view, you will need a little "technique" in order to have pagination. You will paginate on
@prodcats
, not@products
...This approach is way faster, WHEN DEALING WITH
many_to_many
, though not 100% politically correct, I must admit.