我试着这样做:
Things.order("name").group("category_name")
我期待结果是这样的:
[
{
"category_name": "Cat1",
"things":
[
{ "name": "Cat1_Thing1" },
{ "name": "Cat1_Thing1" }
]
},
{
"category_name": "Cat2",
"things":
[
{ "name": "Cat2_Thing3" },
{ "name": "Cat2_Thing4" }
]
}
]
所以我希望得到一个“类别”数组,每个类别都包含一个属于该类别的“项目”。相反,它似乎给了我一个列表,按我分组的字段排序。
注意: category_name
是thing
表中的一列。
答案 0 :(得分:1)
一种选择是在Rails中进行分组(它返回一个哈希值)
Things.order("name").group_by(&:category_name)
#=> {"cat1" => [thing1,thing2,..], "cat2" => [thing3,thing4,..],..}
答案 1 :(得分:1)
尝试类似
的内容my_grouping = Category.includes(:things).
select("*").
group('categories.id, things.id').
order('name')
=> #<ActiveRecord::Relation [#<Category id: 1, name: "Oranges">, #<Category id: 2, name: "Apples">]>
但是,您仍然需要通过Thing
访问my_grouping.things
个对象,它们已经在您手中,您无需等待结果。这可能是您正在寻找的那种互动,而不是将它们映射到实际的Array
。
答案 2 :(得分:1)
ActiveRecord :: Base#group执行SQL GROUP BY。我想,但我不确定(取决于您的数据库适配器),因为您没有指定任何SELECT子句,您将获得每个类别的第一条记录。
为了实现你想要的,有不同的方式。
例如,使用#includes
:
Category.includes(:things).map do |category|
{
category_name: category.name,
things: things.sort_by(&:name).map{|t| {name: t.name} }
}
end.to_json
请注意,将模型序列化为json的标准(尽管经常不赞成)是使用(并在需要时覆盖)as_json and to_json。所以你会有类似的东西:
class Category < ActiveRecord::Base
def as_json( options = {} )
defaults = { only: :name, root: false, include: {links: {only: :name}} }
super( defaults.merge(options) )
end
end
像这样使用:
Category.includes(:links).map(&:to_json)
修改强>
由于category_name只是一个列,您可以这样做:
Thing.order( :category_name, :name ).sort_by( &:category_name ).map do |category, things|
{ category_name: category, things: things.map{|t| {name: t.name} } }
end.to_json
这样的事情可能属于模型:
def self.sorted_by_category
order( :category_name, :name ).sort_by( &:category_name ).map do |category, things|
{ category_name: category, things: things.map{|t| {name: t.name} } }
end
end
所以你可以这样做:
Thing.sorted_by_category.to_json
通过这种方式,你甚至可以进一步扩大范围:
Thing.where( foo: :bar ).sorted_by_category.to_json