鉴于是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 ]
我发现了另一个关于按关联的单个属性进行排序的问题,但这种方法仅适用于真实属性。任何有用的解决方案都会有所帮THX!
答案 0 :(得分: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>
]
答案 1 :(得分:0)
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)