Ciao a tutti, stavo facendo delle prove su alcune tabelle che ho nel DB. Cerco di illustrare al meglio la situazione: USER - ROLES - OPERATIONS Un utente può avere più ruoli, un ruolo può fare più operazioni, quindi in pratica 2 associazioni molti-a-molti. In più nel db ho le relative tabelle diciamo di join, roles_users e operations_roles. Come posso recuperare tutte le operazioni di un determinato utente, che appartiene ad un determinato ruolo? Io ho fatto in un detemrinato modo ma nn mi sembra per niente elegante, avete dei consigli? GRAZIEE!!!!
on 24.04.2008 15:59
on 24.04.2008 16:19
Rapidissimo, a occhio non so se funziona, aggiungi ad User: has_many :operations, :through => :roles http://wiki.rubyonrails.org/rails/pages/Beginner+Howto+on+has_many+:through -- blog: www.lucaguidi.com Pro-Netics: www.pro-netics.com Sourcesense - making sense of Open Source: www.sourcesense.com
on 24.04.2008 16:27
On Apr 24, 2008, at 3:59 PM, Alessandro Del coco wrote: > In più nel db ho le relative tabelle diciamo di join, roles_users e > operations_roles. > > Come posso recuperare tutte le operazioni di un determinato utente, > che > appartiene ad un determinato ruolo? Dato che non c'e' legame diretto fra utenti e operazioni, direi che la tua domanda non ha molto senso... oppure non ti sei spiegato bene :-) S.
on 24.04.2008 16:33
On Apr 24, 2008, at 3:59 PM, Alessandro Del coco wrote: > In più nel db ho le relative tabelle diciamo di join, roles_users e > operations_roles. Ah, quindi sono in relazione molti-a-molti... ecco cosa mi era sfuggito. > > Come posso recuperare tutte le operazioni di un determinato utente, > che > appartiene ad un determinato ruolo? > Io ho fatto in un detemrinato modo ma nn mi sembra per niente > elegante, > avete dei consigli? In teoria "has_many :operations, :through => :roles", ma... "You can only use a :through query through a belongs_to or has_many association on the join model." S.
on 28.04.2008 11:09
Spiego meglio la situazione: 1) model USER has_and_belongs_to_many :roles attr_accessible :roles 2)model ROLE has_and_belongs_to_many :operations attr_accessible :operations 3)model OPERATION has_and_belongs_to_many :roles attr_accessible :roles Premetto che l'autenticazione è gestita da RESTful Authentication che crea current_user quindi io ho pensato di fare in questo modo: current_user.roles.operations L'errore che mi da è il seguente: undefined method `operations' for Role(id: integer, name: string):Class Ho provato anche con :through, ma mi restituisce sempre un errore Invalid source reflection macro :has_and_belongs_to_many for has_many :operations, :through => :roles. Use :source to specify the source reflection.
on 28.04.2008 11:39
allora, la tua pare essere una doppia associazione molti a molti,
dunque l'has many through deve passare per i join model (N.B. con has
many through le tabelle di join devono diventare veri e propri
modelli)
class User
has_many :roles, :through=>:user_roles
has_many :user_roles
end
class UserRole
belongs_to :user
belongs_to :role
end
class Roles
has_many :users, :through=>:user_roles
has_many :user_roles
has_many :operations, :through=>:role_operations
has_many :role_operations
end
class RoleOperation
belongs_to :role
belongs_to :operation
end
class Operation
has_many :roles, :through=>:role_operations
has_many :role_operations
end
ora per trovare tutte le operations dovrebbe essere possibile
semplicemente definire nel modello User:
has_many :operations, :through => :roles
N.B. non ho provato con una relazione tipo has_many through mentre con
la has_many semplice dal join model funziona
In alternativa puoi usare una has_many operations con un :finder_sql:
has_many :operations, , :finder_sql =>
'SELECT DISTINCT operations.* ' +
'FROM operations o, role_operations ro, user_roles ur ' +
'WHERE ur.user_id = #{id} AND ro.role_id = ur.role_id and
o.id=ro.operation_id'
ciao,
Luca
on 28.04.2008 11:49
Ciao Luca, ti ringrazio della spiegazione. Smanettando un pò, sono riuscito ad avere lo stesso risultato semplicemnte facendo così: roles = current_user.roles @oper = roles.first.operations Adesso sto cercando di scoprire bene il funzionamento di first. GRAZIE!!!! Luca Mearelli wrote: > allora, la tua pare essere una doppia associazione molti a molti, > dunque l'has many through deve passare per i join model (N.B. con has > many through le tabelle di join devono diventare veri e propri > modelli) > > > class User > has_many :roles, :through=>:user_roles > has_many :user_roles > end > > class UserRole > belongs_to :user > belongs_to :role > end > > class Roles > has_many :users, :through=>:user_roles > has_many :user_roles > > has_many :operations, :through=>:role_operations > has_many :role_operations > end > > class RoleOperation > belongs_to :role > belongs_to :operation > end > > class Operation > has_many :roles, :through=>:role_operations > has_many :role_operations > end > > ora per trovare tutte le operations dovrebbe essere possibile > semplicemente definire nel modello User: > > has_many :operations, :through => :roles > > N.B. non ho provato con una relazione tipo has_many through mentre con > la has_many semplice dal join model funziona > > In alternativa puoi usare una has_many operations con un :finder_sql: > > has_many :operations, , :finder_sql => > 'SELECT DISTINCT operations.* ' + > 'FROM operations o, role_operations ro, user_roles ur ' + > 'WHERE ur.user_id = #{id} AND ro.role_id = ur.role_id and > o.id=ro.operation_id' > > ciao, > Luca
on 28.04.2008 11:53
On Mon, Apr 28, 2008 at 11:49 AM, Alessandro Del coco <menestra@tele2.it> wrote: > Ciao Luca, > > ti ringrazio della spiegazione. > Smanettando un pò, sono riuscito ad avere lo stesso risultato > semplicemnte facendo così: > > roles = current_user.roles > @oper = roles.first.operations first ti da il primo ruolo nell'enumerable roles dunque roles.first.operations sono le operazioni associate al primo ruolo, i.e. se hai due ruoli con operazioni associate diverse cosi trovi solo le operazioni del primo e non quelle del secondo. ciao, Luca
on 28.04.2008 12:06
Grazie ancora, ma allora non c'è qualcosa che a posto di first riprende tutti i ruoli? Luca Mearelli wrote: > On Mon, Apr 28, 2008 at 11:49 AM, Alessandro Del coco > <menestra@tele2.it> wrote: >> Ciao Luca, >> >> ti ringrazio della spiegazione. >> Smanettando un p�, sono riuscito ad avere lo stesso risultato >> semplicemnte facendo cos�: > >> roles = current_user.roles >> @oper = roles.first.operations > > first ti da il primo ruolo nell'enumerable roles > dunque roles.first.operations sono le operazioni associate al primo > ruolo, i.e. se hai due ruoli con operazioni associate diverse cosi > trovi solo le operazioni del primo e non quelle del secondo. > > ciao, > Luca
on 28.04.2008 14:52
Alessandro Del coco wrote: > Grazie ancora, > > ma allora non c'è qualcosa che a posto di first riprende tutti i ruoli? > @oper = roles.collect {|r| r.operations}.flatten.uniq
on 28.04.2008 14:54
oppure, piu' rubioso ancora: @oper = roles.collect(&:operations).flatten.uniq
on 28.04.2008 15:49
Puoi aggiungere al modello User un metodo operations: def self.operations roles.collect(&:operations).flatten.uniq end Così avrai direttamente il metodo operations per ogni istanza. Stile pino = User.find(:first) pino.operations (ritorna array di operations...) - Show quoted text - On Mon, Apr 28, 2008 at 2:54 PM, Claudio Petasecca Donati <
on 28.04.2008 17:10
anche se collect usato così non l'ho capito... a me dice expected Proc in irb. Che uso è esattamente? On Mon, Apr 28, 2008 at 3:48 PM, giovanni lion <giovanni.lion@gmail.com>
on 28.04.2008 17:23
giovanni lion wrote: > anche se collect usato cos� non l'ho capito... a me dice expected Proc in > irb. Che uso � esattamente? > > On Mon, Apr 28, 2008 at 3:48 PM, giovanni lion <giovanni.lion@gmail.com> Rails estende la classe Symbol con un metodo to_proc: class Symbol def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } end end Chiamare > roles.collect(&:operations) equivale a chiamare > roles.collect(:operations.to_proc) ovvero > roles.collect {|r| r.send(:operations) } quindi > roles.collect {|r| r.operations } Questa estensione della classe Symbol e' definita solo in Rails, non in Ruby. Sara' integrata nel prossimo Ruby 1.9 Ecco perche' non ti funziona in irb
on 28.04.2008 17:27
Infatti stavo giusto cercando ruby 1.9 e le novità sui lambda... Buono a sapersi grazie! 2008/4/28 Claudio Petasecca Donati <cpetasecca@gmail.com>: