如何通过关系显示has_many的唯一logging?
我想知道什么是通过Rails3中的关系来显示来自has_many的唯一logging的最佳方式。
我有三个模型:
class User < ActiveRecord::Base has_many :orders has_many :products, :through => :orders end class Products < ActiveRecord::Base has_many :orders has_many :users, :through => :orders end class Order < ActiveRecord::Base belongs_to :user, :counter_cache => true belongs_to :product, :counter_cache => true end
比方说,我想列出客户已经在他们的显示页面上订购的所有产品。
他们可能已经多次订购一些产品,所以我使用counter_cache根据订单数量以降序排列显示。
但是,如果他们多次订购产品,我需要确保每个产品只列出一次。
@products = @user.products.ranked(:limit => 10).uniq!
当一个产品有多个订单logging时工作,但如果一个产品只被订购了一次,则产生一个错误。 (排名是在别处定义的自定义sorting函数)
另一种select是:
@products = @user.products.ranked(:limit => 10, :select => "DISTINCT(ID)")
我不确定我在这里是正确的做法。
有没有其他人解决这个问题? 你遇到了什么问题? 我在哪里可以find更多关于.unique的区别! 和DISTINCT()?
通过has_many关系生成唯一logging列表的最好方法是什么?
谢谢
你是否试图在has_many关联中指定:uniq选项:
has_many :products, :through => :orders, :uniq => true
从Rails文档 :
:uniq
如果为true,则将从集合中省略重复项。 与…一起使用。
更新轨道4:
在Rails 4中, has_many :products, :through => :orders, :uniq => true
已被弃用。 相反,您现在应该has_many :products, -> { distinct }, through: :orders
编写has_many :products, -> { distinct }, through: :orders
。 有关更多信息,请参阅has_many ::截然不同的部分:通过ActiveRecord关联文档中的关系 。 感谢Kurt Mueller在他的评论中指出了这一点。
请注意,从Rails 4的has_many
的有效选项中删除了uniq: true
。
在Rails 4中,你必须提供一个范围来configuration这种行为。 范围可以通过lambdas提供,如下所示:
has_many :products, -> { uniq }, :through => :orders
导轨指南涵盖了这个以及其他方式,您可以使用示波器来过滤关系的查询,向下滚动到4.3.3节:
http://guides.rubyonrails.org/association_basics.html#has-many-association-reference
你可以使用group_by
。 例如,我有一个照片库购物车,我希望通过哪个照片(每张照片可以多次订购,以不同尺寸打印)对订购商品进行分类。 这然后返回一个散列与产品(照片)作为关键,每次它的sorting可以在照片(或不)的上下文中列出。 使用这种技术,您可以实际输出每个给定产品的订单历史logging。 不知道在这种情况下这对你是否有帮助,但我发现它非常有用。 这是代码
OrdersController#show @order = Order.find(params[:id]) @order_items_by_photo = @order.order_items.group_by(&:photo)
@order_items_by_photo
然后看起来像这样:
=> {#<Photo id: 128>=>[#<OrderItem id: 2, photo_id: 128>, #<OrderItem id: 19, photo_id: 128>]
所以你可以做这样的事情:
@orders_by_product = @user.orders.group_by(&:product)
然后当你在你的视图中得到这个,只是循环这样的事情:
- for product, orders in @user.orders_by_product - "#{product.name}: #{orders.size}" - for order in orders - output_order_details
这样可以避免仅返回一个产品时出现的问题,因为您始终知道它将以产品作为关键字和您的订单数组返回散列。
对于你想要做的事情可能是过度的,但它确实给你一些不错的select(如订购的date等)来处理数量。