0

我试图这样做:

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

4

3 回答 3

2

尝试类似的东西

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.

于 2013-09-25T21:17:19.370 回答
1

一种选择是在 Rails 中进行分组(它返回一个哈希)

Things.order("name").group_by(&:category_name)
#=> {"cat1" => [thing1,thing2,..], "cat2" => [thing3,thing4,..],..}
于 2013-09-25T21:16:24.383 回答
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 和 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
于 2013-09-25T21:18:35.483 回答