2009-09-26 7 views
9

Sono un po 'confuso su come funziona anche se funziona correttamente. Ho un modello che ha due associazioni con lo stesso modello.has_one e has_many nello stesso modello. Come li rintraccia i binari?

La società ha un proprietario e un'azienda ha molti dipendenti degli utenti della classe.

qui è il mio modello di società:

class Company < ActiveRecord::Base 
    validates_presence_of :name 

    has_many :employee, :class_name => 'User' 
    has_one :owner, :class_name => 'User' 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

qui è il mio modello di utente:

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
end 

Ora assumendo ho 3 dipendenti di questa azienda compreso il proprietario. Quando creo la società, per prima cosa imposto il proprietario al dipendente con ID 1 e gli altri due (2,3) vengono aggiunti all'elenco dei dipendenti impostando il proprio company_id (user.company = company). Tutti e tre hanno il loro company_id impostato sull'id dell'azienda che possiamo assumere è 1

quando chiedo per company.owner, ottengo l'utente giusto e quando faccio company.employee, ottengo tutti e tre.

Se cambio il proprietario in utente 2, rimuove automaticamente l'utente 1 dai dipendenti impostando it_azienda su nil. Questo va bene e se lo ricollego come semplice impiegato tutto è ancora buono.

Come diavolo le guide sanno quale è quale? Quello che voglio dire è come fa a sapere che un dipendente è proprietario e non solo un dipendente? Niente nello schema lo definisce.

Ho la sensazione che dovrei invertire l'associazione dei proprietari e rendere l'azienda appartenente a un utente.

risposta

12

Come lo avete ora, non c'è nulla per distinguere i proprietari dai dipendenti. Il che significa che ti imbatterai in problemi una volta che inizi a rimuovere persone o tenti di cambiare proprietà.

Come fa notare François, si sta solo facendo notare che il proprietario è l'utente che appartiene all'azienda con l'ID più basso.

Per risolvere il problema vorrei che i miei modelli si riferissero nel seguente manuale.

class Company < ActiveRecord::Base 
    belongs_to :owner, :class_name => "user" 
    has_many :employees, :class_name => "user" 
    validates_presence_of :name 
    accepts_nested_attributes_for :owner, :allow_destroy => true 
end 

class User < ActiveRecord::Base 
    include Clearance::User 
    attr_accessible :lastname, :firstname #other attr are whitelisted in clearance gem 
    validates_presence_of :lastname, :firstname 
    belongs_to :company 
    has_one :company, :foreign_key => :owner_id 
end 

Dovrai aggiungere un'altra colonna denominata owner_id alla tabella Società, ma ciò definisce più chiaramente le tue relazioni. E eviterà qualsiasi problema associato alla modifica del proprietario. Prendi nota che potrebbe esserci una dipendenza ciclica se segui questo percorso e hai il tuo database impostato in modo tale che entrambi gli utenti.company_id e companies.owner_id non possono essere nulli.

Non sono sicuro di quanto bene accept_nested_attributes_for giocherà con una relazione belongs_to.

+0

Terminato facendo questo e sul lato utente, ho fatto appartiene a: datore di lavoro,: class_name => "Azienda" che dovevo fare per prevenire un conflitto con user.company, ora user.company è la società e la società di proprietà .employer is ... hai capito il punto: P – nkassis

0

Si potrebbe avere un modello chiamato proprietà -

ownership belongs_to company 
ownership belongs_to user 

user has_many ownerships 
company has_one ownership 
5

has_one è zucchero sintattico per:

has_many :whatevers, :limit => 1 

ha un po 'aggiunge il :limit => 1, garantendo in tal modo solo 1 record è mai tornato. Nella tua ha una dichiarazione, assicurati di avere una clausola :order, per restituire il record giusto in tutte le circostanze. In questo caso, metterei un flag sull'Impiegato per indicare chi è il proprietario e ordinare per questa colonna per ottenere il record corretto 1.

La tua domanda su come Rails lo sa è perché la maggior parte dei database restituirà i record nel loro ordine di chiave primaria. Quindi, il primo dipendente aggiunto ha l'ID 1, quindi verrà restituito il primo.