2013-12-09 78 views
1

鑑於電影和演員在m:n關係。我想要做的就是找回角色名單,由他們扮演的電影數量排序DataMapper:通過關聯計數排序結果(相關對象的數量)

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 ] 

我發現了另一個問題關於通過關聯的單個屬性進行排序,但此方法僅適用於真實屬性。任何可用的解決方案都會有幫助謝謝!

回答

2

服用由肖恩拉金作爲出發點的答案我結束了這樣的事情:

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> 
] 
+0

如果您想從該數據返回一個散列,就像下面這樣簡單:'actors = repository(:default).adapter.select( 「SELECT actors.name,count(actor_movies.actor_name)AS count」+ 「 FROM演員「+ 」JOIN actor_movies WHERE actors.name = actor_movies.actor_name「 + 」GROUP BY actors.name「 + 」ORDER BY計數(actor_movies.actor_name)降序「 + 」LIMIT 5;「 ).MAP {|結構| {:name => struct.name,:count => struct.count}}' –

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)