我一直在努力解决这个问题几个小时,现在还没有找到一个干净的解决方案。看来我对铁轨不太好......
无论如何,我有以下内容:
在代码中:
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
现在,我想做的是分两步进行排序。第一种文章由他们的Articles.name,然后在内部按Aspect.name排序(注意,不是中间人)。
例如,按字母顺序排列(对不起,如果表示法不正确):
[{
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'
]
}]
再次注意,这些是按方面名称(形状前的颜色)排序,而不是每行的特定值(绿色前的红色)。我的目的是在视图中的表格中显示这些内容。
结果如下:
这是我正在使用的代码:
<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>
我还没有找到一种在rails中执行此操作的好方法(不使用N查询)。任何人都可以告诉我一个很好的方法(如果我的方法错了,甚至改变观点)?
(我找到了similar question in hyphen)
更新:这是我在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
但我想以轨道方式做到这一点。
更新:添加了视图代码。这可能会让我的困境更好一些。
答案 0 :(得分:3)
在尝试了另一个答案之后,我找到了一种从模型中做到这一点的方法。我不确定这是否是Right Way™,但它似乎是一个可行的解决方案(让数据库引擎对其进行排序)。
在Aspect模型中,我改变了这一行:
has_many :line_aspects
进入这个:
has_many :line_aspects, :include => :article, :order => 'articles.name'
尽管如此,我还是希望听到更多人的意见。
答案 1 :(得分:1)
这只是部分解决方案,因为它无法完全解决您的问题。
您可以使用named_scope
按相应字段对模型进行排序。有点像:
named_scope :ordered, :order => "name ASC"
这是一个简单的解决方案(至少语法方面,不确定复杂性)。我可以预见的唯一问题是,您无法在单个查询中对多个named_scope进行排序。
对于第二种排序,您可以对获得的集合使用Enumerable#sort_by
或array.sort
。
希望这有点帮助:)
答案 2 :(得分:0)
此查询提取所有文章并急切加载其方面,并按文章名称和ascpect名称对其进行排序:
@articles = Article.all(:include => [ :aspects ], :order => "articles.name asc, aspects.name asc")