Kulgar
Kulgar

Reputation: 1865

Rails - how to order a model by its has many association?

I have two models:

#Product
class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
  attr_accessible :name
  ...
end

#Category
class Category < ActiveRecord::Base
  has_and_belongs_to_many :products, :order => "name ASC"

  attr_accessible :name, :priority
end

And I'd like to order my products by the highest priority category and then by products' name

For example I have: 3 categories:

3 products:

And I'd like them to be ordered like that:

How may I do that in Rails? I don't want my products to be duplicated, I know it would be easy to do something like:

Category.order("priority ASC").each do |cat|
  cat.products.order("name ASC").each do |product|
  end
end

But in that case Kiwi, Chocolate Ice Cream and Cookies would be duplicated because they all have several categories. Is there a simple way to remove duplicates? Or is there a way to order products directly by category highest priority?

Edit: more details about what I want to achieve

What I want in fact, is a huge table where, at the left, I have all the products (and only one line per unique product) sorted by categories... So that I can have something like this:

See? Even if a fruit is a dessert and sweet, I want it to appears only one time in this table. And I want products to appear in their "most important" category (that why I thought about "priority").

As this huge table will be used to edit products, I want to be able to easily access products' attributes (there'll be one column per attribute). So I really need to do as minimum database requests as possible.


Thanks to anyone who may help me! Kulgar

Upvotes: 6

Views: 3084

Answers (2)

Rahul
Rahul

Reputation: 412

Maybe try this

products = Product.joins(:categories).order("categories.priority ASC, products.name ASC")

This will fetch duplicated values as well. Let's say you wish to fetch names, maybe you could try this

products.map(&:name).uniq

Upvotes: 1

shweta
shweta

Reputation: 8169

To avoid duplicates you can try this,

Product.joins(:categories).group("products.name").order("categories.priority ASC, products.name ASC")

Upvotes: 8

Related Questions