How to sort objects in many-to-many relationship in ruby ​​on rails?

I have been trying to solve this problem for hours and have been unable to come up with a clean solution. I don't seem to be too good with rails ...

Anyway, I have the following:

Diagram

In code:

class Article < ActiveRecord::Base
  has_many :line_aspects
  has_many :aspects, :through => :line_aspects
  #plus a 'name' field
end

class LineAspect < ActiveRecord::Base
  belongs_to :article
  belongs_to :aspect
  #plus a 'value' field
end

class Aspect < ActiveRecord::Base
  has_many :line_aspects
  has_many :articles, :through => :line_aspects
  #plus a 'name' field
end

      

Now, what I would like to do is sort them in two steps. First kind of articles by their articles .name, and then internally sort them by Aspect.name (note, not the middleman).

For example, in alphabetical order (sorry if the notation is wrong):

[{
   article => 'Apple',
   line_aspects => [
      {:value => 'red'}, #corresponding to the Attribute with :name => 'color'
      {:value => 'small'} #corresponding to the Attribute with :name => 'shape'
   ]
},{
   article => 'Watermelon',
   line_aspects => [
      {:value => 'green'}, #corresponding to the Attribute with :name => 'color'
      {:value => 'big'} #corresponding to the Attribute with :name => 'shape'
   ]
}]

      

Note again that they are ordered by aspect name (color in front of shape) instead of specific values ​​for each row (red to green). My intention is to display them in a table in a view.

With this result:

Table

This is the code I am using:

<table>
  <tr>
    <th>Category</th>
    <% @articles.each do |article| -%>
      <th><%= link_to article.name, article -%></th>
    <% end -%>
  </tr>

  <% @aspects.each do |aspect| -%>
    <tr>
      <td><%= aspect.name -%></td>

      <% aspect.line_aspects.each do |line_aspect| -%>
        <td><%= line_aspect.value %></td>
      <% end -%>
    </tr>
  <% end -%>
</table>

      

I haven't found a good way to do this in rails yet (without resorting to N queries). Can anyone tell me a good way to do this (even by changing the view if my approach is wrong)?

(I found a similar question in a hyphen )

UPDATE: This is how I would do it in SQL:

SELECT line_aspects.value FROM line_aspects, aspects, articles 
WHERE articles.id = line_aspects.article_id 
   AND aspects.id = line_aspects.aspect_id
ORDER BY aspects.name, articles.name

      

But I would like to do it with rails.

UPDATE: Added view code. Which might solve my predicament a little better.

+2


a source to share


3 answers


After trying another answer I found a way to do it from the model. I'm not sure if this is the Right Way β„’, but it seems like a viable solution (to let the database engine sort it).

In the Aspect model, I changed this line:

has_many :line_aspects

      



In it:

has_many :line_aspects, :include => :article, :order => 'articles.name'

      

I would still like to hear more people if possible.

+3


a source


This is only a partial solution as it does not completely solve your problem.

You can use named_scope

to order the model according to the corresponding field. Sort of: named_scope :ordered, :order => "name ASC"

This is a simple solution (at least syntax wise, not sure about the complexity). The only problem I can foresee is that you cannot link multiple named_scopes to sort in a single query.



For the second sort, you can use Enumerable#sort_by

or array.sort

on the resulting collection.

Hope this helps a little :)

+1


a source


This query fetches all articles and loads their aspects and sorts them by name and object name:

@articles = Article.all(:include => [ :aspects ], :order => "articles.name asc, aspects.name asc")

      

0


a source







All Articles