tua condizione has_one
non funzionerà mai in Rails, per quanto ne so.
È necessario un esplicito has_one
o belongs_to
o has_many per "collegamento", su entrambe le tabelle. Quindi, se hai due "link", hai bisogno di due has_one
e due belongs_to
. Ecco come funziona.
In secondo luogo, penso che dovresti riconsiderare i tuoi modelli. Il modo in cui lo fai, una persona non può essere il presidente di un club e un dipendente, allo stesso tempo. O essere il presidente di due club. Anche se non li hai adesso, possono venire in futuro - è più facile rimanere flessibili in questo momento.
Un modo flessibile per fare ciò è utilizzare un has_many :through
con una tabella intermedia che specifica il ruolo. In altre parole:
# The memberships table has a person_id, club_id and role_id, all integers
class Membership < ActiveRecord::Base
belongs_to :club
belongs_to :person
validates_presence_of :role_id
validates_numericality_of :role_id
end
class Club < ActiveRecord::Base
has_many :memberships, :dependent => :delete_all
has_many :people, :through => :memberships
end
class Person < ActiveRecord::Base
has_many :memberships, :dependent => :delete_all
has_many :clubs, :through => :memberships
end
Ora, partendo dal presupposto che ROLE_ID = 0 significa dipendente, ROLE_ID = 1 significa presidente, e ROLE_ID = 2 significa vice_president, è possibile utilizzarlo in questo modo:
tyler = Person.find(1) # person_id is 1
other = Person.find(2) # person_id is 2
c = Club.find(1) # club_id is 1
tyler.clubs # returns all the clubs this person is "member" of
c.people # returns all the "members" of this club, no matter their role
#make tyler the president of c
tyler.memberships.create(:club_id => 1, :role_id => 1)
#make other the vicepresident of c
#but using c.memberships instead of other.memberships (works both ways)
c.memberships.create(:person_id => 2, :role_id => 1)
#find the (first) president of c
c.memberships.find_by_role_id(1).person
#find the (first) vicepresident of c
c.memberships.find_by_role_id(2).person
#find all the employees of c
c.memberships.find_all_by_role_id(0).collect { |m| m.person }
#find all the clubs of which tyler is president
tyler.memberships.find_all_by_role_id(1).collect { |m| m.club }
Note aggiuntive :
- Si potrebbe completare questo con un tavolo ruoli e modello. I ruoli avrebbero solo un nome, i ruoli corrisponderebbero alle relazioni
have_many
e al ruolo belong_to
.In alternativa, è possibile definire i metodi nelle appartenenze per ottenere il nome del ruolo (se 0, restituisce "impiegato", se 1, "presidente", ecc.
- È possibile aggiungere convalide su membri, quindi non più di una persona può essere nominata presidente di un determinato club, o dello stesso dipendente nello stesso club due volte Più tardi, se inizi a ricevere "casi eccezionali" in cui una persona deve trovarsi in due punti, dovrai solo adattare le convalide
Ok, questo sembra decisamente una struttura migliore. Tuttavia non sono sicuro di come la cosa dipendente funzioni in questo. La designazione del dipendente è davvero indipendente se fa parte di un club o no, quindi non penso che dovrebbe far parte del tavolo dei soci. Per inciso, utilizzo già un modello di ruoli per i diversi ruoli dei dipendenti che abbiamo. Quindi forse sul modello Persona ci dovrebbe essere un'associazione con un has_one EmployeeRole e che fornisce il tipo di dipendente? – adimitri
Ciao! Non sono sicuro di capire cosa intendi per 'davvero indipendente se fanno parte di un club o no'. Se si dispone di una tabella ruoli con ruoli dipendenti, è possibile aggiungere altri 2 ("presidente" e "vicepresidente") e utilizzare solo una cosa. Perché vuoi che siano separati? – kikito
Questa applicazione è per un'organizzazione governativa studentesca in un campus universitario. Finanziano molti club gestiti da studenti e con 4 posizioni di e-board (Presidente, VP, Segretario Tesoriere). I dipendenti sono del governo studentesco e anche studenti, ma non ha nulla a che fare con il club. Quindi possono far parte di un club e-board e un dipendente. – adimitri