Reputation: 430
I have two models Hotel and Address. Relationships are:
class Hotel
belongs_to :user
has_one :address
accepts_nested_attributes_for :address
and
class Address
belongs_to :hotel
And I need to save in hotels table and in addresses table from one form.
The input form is simple:
<%= form_for(@hotel) do |f| %>
<%= f.text_field :title %>
......other hotel fields......
<%= f.fields_for :address do |o| %>
<%= o.text_field :country %>
......other address fields......
<% end %>
<% end %>
Hotels controller:
class HotelsController < ApplicationController
def new
@hotel = Hotel.new
end
def create
@hotel = current_user.hotels.build(hotel_params)
address = @hotel.address.build
if @hotel.save
flash[:success] = "Hotel created!"
redirect_to @hotel
else
render 'new'
end
end
But this code doesn't work.
ADD 1 Hotel_params:
private
def hotel_params
params.require(:hotel).permit(:title, :stars, :room, :price)
end
ADD 2
The main problem is I don't know how to render form properly. This ^^^ form doesn't even include adress fields (country, city etc.). But if in the line
<%= f.fields_for :address do |o| %>
I change :address to :hotel, I get address fields in the form, but of course nothing saves in :address table in this case. I don't understand the principle of saving in 2 tables from 1 form, I'm VERY sorry, I'm new to Rails...
Upvotes: 2
Views: 7297
Reputation: 76774
Bottom line here is you need to use the f.fields_for
method correctly.
--
Controller
There are several things you need to do to get the method to work. Firstly, you need to build the associated object, then you need to be able to pass the data in the right way to your model:
#app/models/hotel.rb
Class Hotel < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
end
#app/controllers/hotels_controller.rb
Class HotelsController < ApplicationController
def new
@hotel = Hotel.new
@hotel.build_address #-> build_singular for singular assoc. plural.build for plural
end
def create
@hotel = Hotel.new(hotel_params)
@hotel.save
end
private
def hotel_params
params.require(:hotel).permit(:title, :stars, :room, :price, address_attributes: [:each, :address, :attribute])
end
end
This should work for you.
--
Form
Some tips for your form - if you're loading the form & not seeing the f.fields_for
block showing, it basically means you've not set your ActiveRecord Model
correctly (in the new
action)
What I've written above (which is very similar to that written by Pavan
) should get it working for you
Upvotes: 2
Reputation: 33542
You are using wrong method
for appending your child with the parent.And also it is has_one relation
,so you should use build_model
not model.build
.Your new
and create
methods should be like this
class HotelsController < ApplicationController
def new
@hotel = Hotel.new
@hotel.build_address #here
end
def create
@hotel = current_user.hotels.build(hotel_params)
if @hotel.save
flash[:success] = "Hotel created!"
redirect_to @hotel
else
render 'new'
end
end
Update
Your hotel_params
method should look like this
def hotel_params
params.require(:hotel).permit(:title, :stars, :room, :price,address_attributes: [:country,:state,:city,:street])
end
Upvotes: 6
Reputation: 3412
You should not build address again
class HotelsController < ApplicationController
def new
@hotel = Hotel.new
end
def create
@hotel = current_user.hotels.build(hotel_params)
# address = @hotel.address.build
# the previous line should not be used
if @hotel.save
flash[:success] = "Hotel created!"
redirect_to @hotel
else
render 'new'
end
end
Upvotes: 2