2013-11-24 11 views
10

Sono un principiante in Rails e ho un problema con le associazioni ActiveRecords.
Sto creando servizio di noleggio auto semplice e ho fatto le seguenti associazioni:Rails belongs_to_many

class Client < ActiveRecord::Base 
    has_many :rentals 
    has_many :bookings 
    has_many :cars, :through => :rentals 
    has_many :cars, :through => :bookings 
end 

class Rental < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_one :car 
end 

class Booking < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_one :car 
end 

Che cosa ho bisogno è di avere una macchina appartenente a molte prenotazioni e noleggio mentre ogni prenotazione e il noleggio può avere una sola auto assegnato.

class Car < ActiveRecord::Base 
    # belongs_to_many :bookings 
    # belongs_to_many :rentals 
end 

Come devo fare?

risposta

28

Se una macchina può avere molte prenotazioni/noleggi, ma una prenotazione/noleggio può avere solo un'auto, stai guardando una classica situazione belongs_to/has_many. Sembra che tu sia inciampato nella distinzione tra belongs_to e has_one - non è una grammatica, ma una questione di dove si trova la colonna chiave esterna nel tuo database.

  • belongs_to: "Sono correlato esattamente a uno di questi e ho la chiave esterna."
  • has_one: "Sono correlato esattamente a uno di questi e ha la chiave esterna."
  • has_many: "Sono collegato a molti di questi e hanno la chiave esterna."

noti che has_one e has_many entrambi implicano c'è un belongs_to sul l'altro modello, dato che è l'unica opzione in cui "questo" modello ha la chiave esterna. Nota anche che questo significa che has_one deve essere usato solo quando si ha una relazione uno-a-uno, non una uno-a-molti.

Prendendo questo in considerazione, vorrei sostituire il has_one :car con belongs_to :car in entrambi i vostri modelli di noleggio e di prenotazione, e il luogo has_many :bookings e has_many :rentals nel vostro modello di auto. Assicurarsi inoltre che le tabelle rentals e bookings abbiano una colonna car_id; non ci dovrebbero essere colonne relative al noleggio o alla prenotazione nella tabella cars.

+0

Questo è quello che ho capito ieri, ma avevo bisogno di una conferma. Grazie per averlo spiegato! – squixy

+0

Esiste una relazione "Sono correlato a molti di questi e ho le chiavi esterne"? Che cos'è? Grazie! – Ziggy

+2

@Ziggy, non esiste un'opzione che implichi un modello che memorizza più chiavi esterne, poiché ciò non è realmente possibile utilizzando i tipi di colonna SQL standard. Se hai una relazione molti-a-molti (ad esempio, i post hanno molti tag e i tag hanno molti post), dovrebbe essere rappresentato da un terzo modello (ad esempio Tagging) in una configurazione ['has_many: through'] (http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association). – Grantovich

0

Non è possibile fare appartiene a qualcuno. Il più vicino che puoi ottenere è has_and_belongs_to_many, ma non sono sicuro che sia ciò che desideri qui, a meno che tu non possa avere più auto per noleggio/prenotazione. Controlla il guide per una spiegazione completa.

vorrei cambiare in su in questo modo:

class Rental < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    belongs_to :car 
end 

class Booking < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    belongs_to :car 
end 

class Car < ActiveRecord::Base 
    has_many :bookings 
    has_many :rentals 
end 

Inoltre, io non so come i tuoi affitti si riferiscono alle prenotazioni, ma il mio pensiero immediato è che ci dovrebbe essere una qualche relazione tra i due, a causa probabilmente non puoi avere un noleggio senza averlo prenotato, giusto?

2

Sì, c'è un "belongs_to_many" in Rails, una specie di. È un po 'più di lavoro e non è possibile utilizzare i generatori con esso. Si chiama associazione polymorphic.

Anche se si può fare una macchina con molte prenotazioni & affitti, è possibile associare l'auto facendola appartenere a un polimorfo come rentable_vehicle.Il tuo codice sarebbe simile a questo

class Car < ActiveRecord::Base 
    belongs_to :rentable_vehicle, polymorphic: true 
end 

class Rental < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_many :cars, as: :rentable_vehicle 
end 

class Booking < ActiveRecord::Base 
    belongs_to :client, dependent: :destroy 
    has_many :cars, as: :rentable_vehicle 
end