2009-06-14 16 views
7

im un principiante con DataMapper ORM, quindi ho domande su query complesse.Associazione query DataMapper complessa

In primo luogo, gli oggetti di dati qui è semplificata:

class User 
    property :id, Serial 
    property :login, String 

    has n, :actions 
end 

class Item 
    property :id, Serial 
    property :title 

    has n, :actions 
    has n, :users, :through => :actions 
end 

class Action 
    property :user_id, Integer 
    property :item_id, Integer 

    belongs_to :item 
    belongs_to :user 
end 

Questo è come i dati in db assomiglia:

+ ------- + + ------- + + ------- + 
| Users | | Items | | Actions | 
+ ------- + + ------- + + ------- + 
| 1 | u1 | | 3 | i1 | | 1 | 4 | 
| 2 | u2 | | 4 | i2 | | 1 | 3 | 
| ....... | | 5 | i3 | | 1 | 4 | 
+ ------- + | ....... | | 1 | 5 | 
      + ------- + | 1 | 6 | 
         | 1 | 3 | 
         | ....... | 
         + ------- + 

Così, ad esempio, l'utente 1 ha visto alcuni elementi N tempo. E quello che non riesco a capire, come selezionare gli elementi e il loro ammontare di azioni relative all'utente.

Ad esempio, il risultato per l'utente 1 dovrebbe essere così:

+ -------------------- | 
| Items (item_id, num) | 
+ -------------------- | 
| 3, 2     | 
| 4, 2     | 
| 5, 1     | 
| 6, 1     | 
+ -------------------- + 

P.S. query SQL regolare che corrisponde alle mie esigenze:

SELECT i.id, i.title, COUNT(*) as 'num' 
FROM actions a 
JOIN items i on i.id = a.item_id 
WHERE a.user_id = {USERID} 
GROUP by a.id 
ORDER BY num DESC 
LIMIT 10; 

Quindi, come per fare questo ed è ci sono documenti su query complesse DataMapper?

risposta

2

Per quanto ne so, non esiste un gruppo per operatore in datamapper o uno dei suoi plugin. Se ce ne fossero, andrebbe in dm-aggregates insieme alle funzioni di aggregazione (count, min, max, avg). Ciò rende difficile replicare ciò che si desidera in una query senza utilizzare sql.

si potrebbe provare qualcosa di simile:

require 'dm-aggregates' 

Item.all.map do |item| 
    [item.title,item.actions.count(:user_id=>@user_id)] 
end 

Ma, si potrebbe facilmente prendere il vostro SQL e avvolgerlo in un fn.

class User 
    def item_views 
    repository.adapter.query "SELECT i.id, i.title, COUNT(*) as 'num' 
    FROM actions a 
    JOIN items i on i.id = a.item_id 
    WHERE a.user_id = {USERID} 
    GROUP by a.id 
    ORDER BY num DESC 
    LIMIT 10;" 
    end 
end 

repository.adapter.query restituisce un array di struct in modo che si possa fare cose come

user.item_views[0].title 
12

Nel caso qualcuno si chiede ancora:

Action.aggregate(:item_id, :all.count, :user_id => 1, :order => [item_id.asc]) 

restituirà qualcosa come

[ [ 3, 2 ], 
    [ 4, 2 ], 
    [ 5, 1 ], 
    [ 6, 1 ] 
] 

Non c'è modo di ordinare da tutti.qui qui, ma ti ottengono i dati che desideri :)

+0

Grazie - non è affatto chiaro dalla documentazione di DataMapper. DM produce un codice SQL più stretto di AR, ma per capire come farlo richiede una risposta StackOverflow come questa. –

Problemi correlati