I have the following 4 models
Hotel (name)
has_one :address
has_one :contact
has_one :bank_account
validates_presence_of :name
def build_dependencies
build_contact
build_address
build_bank_account
end
Address (phone, street_address, hotel_id)
belongs_to :hotel
validates_presence_of :phone, :street_address
Contact (name, email, hotel_id)
belongs_to :hotel
validates_presence_of :name, :email
BankAccount (name, number, hotel_id)
belongs_to :hotel
validates_presence_of :name, :number
In a form used to create a Hotel, I take input for both name and email for the Contact model but only phone for the Address model.
HotelController#new
@hotel = Hotel.new
@hotel.build_dependencies #this creates empty Contact and Address to generate the form fields
#render the form to create the hotel
HotelController#create
#receive form data
@hotel = Hotel.new
@hotel.build_dependencies
@hotel.save :validate => false
@hotel.attributes = params[:hotel]
@hotel.save :validate => false
This is the only way I was able to create a Hotel with contact information, phone from address and empty bank account. I had to call
@hotel.save :validate => false
the first time to save the Hotel instance with blank instances of BankAccount, Address, Contact. Then I had to update_attributes on contact and address and then
@hotel.save :validate => false
to ensure that the original form data got saved completely as expected.
This, beyond doubt, is a very bad piece of code. Can anyone tell me how to clean this up?
Address
validates_presence_of :phone, :on => :create, :if => proc { |u| u.creating_hotel? }
validates_presence_of :street, :phone, :on => :update
Contact
validates_presence_of :name, :email :on => :update
def creating_hotel?
addressable_type == 'Hotel'
end
The user sees the :street, :name, :email
fields only after the hotel is created and :phone
during the creation.