【问题标题】:How to sort deeply nested collections with ActiveRecord?如何使用 ActiveRecord 对深度嵌套的集合进行排序?
【发布时间】:2011-09-06 17:38:03
【问题描述】:

我正在构建一个音乐管理 Rails 应用,我的应用的用户将能够制作专辑的有序播放列表,并且每张专辑都有一个有序的歌曲列表。

本质上,这看起来像:

class User < ActiveRecord::Base
  has_many :playlists, :order => "position"
  has_many :albums, :through => :playlists
end

class Playlist < ActiveRecord::Base
  belongs_to :user
  belongs_to :album
end

class Album < ActiveRecord::Base
  has_many :songs, :order => "position"
  has_many :playlists
end

class Song < ActiveRecord::Base
  belongs_to :album
end

(我使用acts_as_list 在歌曲和播放列表表中使用position 列来分别管理歌曲和播放列表的排序顺序。)

现在我想查找给定用户的所有歌曲列表(按顺序)。如果我将此范围添加到 Song 模型中:

scope :for_user, lambda{|user|
  joins(:album => {:playlists => :user}).
  where(:'users.id' => user.id)
}

我可以这样做,但返回的记录没有按顺序排列。相反,我希望看到每首歌曲首先按其专辑的用户播放列表位置排序,然后按歌曲在该专辑中的位置排序。换句话说,如果用户想要按顺序播放专辑 A、B 和 C,我正在寻找 A 中所有歌曲的数组(按专辑中的顺序),以及 B 中的所有歌曲(按顺序),加上 C 中的所有歌曲(按顺序)。

我已经在范围内尝试了 ordergroup 子句的几种排列方式,但没有一种能够达到在专辑排序上下文中排序歌曲的预期效果.

【问题讨论】:

    标签: ruby-on-rails activerecord scope acts-as-list


    【解决方案1】:

    你试过了吗:

    scope :for_user, lambda{|user|
      joins(:album => {:playlists => :user}).
      where('users.id' => user.id).
      order('"albums"."position" ASC, "songs"."position" ASC')
    }
    

    ORDER BY sql 子句接受多个参数(请参阅http://www.quackit.com/sql/tutorial/sql_order_by.cfm)。不要使用 GROUP BY,它只在生成聚合时有用(例如http://www.w3schools.com/sql/sql_groupby.asp

    【讨论】:

      【解决方案2】:

      要添加到 m_x 的答案,如果您希望您的代码更加面向对象,您可以像这样构建 order 子句:

      order(Album.arel_table[:position], Song.arel_table[:position])

      【讨论】:

        猜你喜欢
        • 2013-12-03
        • 2021-02-24
        • 1970-01-01
        • 2019-09-14
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        • 1970-01-01
        • 2018-11-22
        相关资源
        最近更新 更多