【问题标题】:DataMapper: Sorting results by association count (number of related objects)DataMapper:按关联计数(相关对象的数量)对结果进行排序
【发布时间】:2013-12-26 16:47:23
【问题描述】:

给定的是 m:n 关系中的电影和演员。我想做的是检索演员列表,按他们出演的电影数量排序。

class Movie
  include DataMapper::Resource
  property :id,     Serial
  property :title,  String
  has n,   :actors, through: Resource
end

class Actor
  include DataMapper::Resource
  property :name,   String, key: true
  has n,   :movies, through: Resource
end

在伪 DM 中我想要的是这样的:

Actor.all order: [ :movies.count ]

我发现了另一个关于按关联的单个属性进行排序的问题,但这种方法仅适用于真实属性。任何可用的解决方案都会有所帮助。谢谢!

【问题讨论】:

    标签: sql ruby associations datamapper ruby-datamapper


    【解决方案1】:

    DataMapper 的文档有点过时,我努力尝试完成与您所做的相同的事情。

    我改为使用直接 MySQL 查询:

    records = repository(:default).adapter.select(“SELECT * FROM actor ORDER BY count(movies) desc;”) 
    

    重要的是要注意,当您使用直接 MySQL 查询时,将返回一个结构,而不仅仅是数据的散列。如果您将此数据作为 JSON 返回,则必须手动将其转换为哈希。

    您可以通过以下方式在 Ruby 1.8-1.9 中将结构转换为哈希:

    actors = repository(:default).adapter.select( "SELECT actors.name, count(actor_movies.actor_name) AS count " + "FROM actors " + "JOIN actor_movies WHERE actors.name = actor_movies.actor_name " + "GROUP BY actors.name " + "ORDER BY count(actor_movies.actor_name) desc " + "LIMIT 5;" ).map{|struct| {:name => struct.name, :count => struct.count}}

    在 Ruby 2.0 中,他们添加了 to_h,因此您可以使用它:

    actors = repository(:default).adapter.select( "SELECT actors.name, count(actor_movies.actor_name) AS count " + "FROM actors " + "JOIN actor_movies WHERE actors.name = actor_movies.actor_name " + "GROUP BY actors.name " + "ORDER BY count(actor_movies.actor_name) desc " + "LIMIT 5;" ).map(&:to_h)

    【讨论】:

      【解决方案2】:

      以 Sean Larkin 的回答为出发点,我最终得到了这样的结果:

      actors = repository(:default).adapter.select(
        "SELECT actors.name, count(actor_movies.actor_name) AS count " +
        "FROM actors " +
        "JOIN actor_movies WHERE actors.name = actor_movies.actor_name " +
        "GROUP BY actors.name " +
        "ORDER BY count(actor_movies.actor_name) desc " +
        "LIMIT 5;"
      )
      
      => [
        #<struct name="Samuel L. Jackson", count=66>,
        #<struct name="Michael Caine", count=64>,
        #<struct name="Robert De Niro", count=59>,
        #<struct name="Harvey Keitel", count=58>,
        #<struct name="Gene Hackman", count=57>
      ]
      

      【讨论】:

      • 如果您想从该数据中返回一个哈希值,那么简单:actors = repository(:default).adapter.select( "SELECT actors.name, count(actor_movies.actor_name) AS count " + "FROM actors " + "JOIN actor_movies WHERE actors.name = actor_movies.actor_name " + "GROUP BY actors.name " + "ORDER BY count(actor_movies.actor_name) desc " + "LIMIT 5;" ).map{|struct| {:name =&gt; struct.name, :count =&gt; struct.count}}
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      相关资源
      最近更新 更多