Reputation: 307
I'm getting the following error when I attempt to submit my nested form.
Cannot modify association 'Appointment#addresses' because the source reflection class 'Address' is associated to 'User' via :has_many
I'm not entirely sure which part of my setup is wrong. To briefly explain, I have Users that have multiple Appointments and multiple Addresses. Each Appointment can happen at a different Address, which is why I'm doing a :has_many association through user (which is correct, right?). Why am I getting this error?
Here are my models:
class User < ActiveRecord::Base
has_many :addresses, dependent: :destroy
has_many :appointments, dependent: :destroy
end
class Appointment < ActiveRecord::Base
belongs_to :user
has_many :addresses, :through => :user
accepts_nested_attributes_for :addresses
end
class Address < ActiveRecord::Base
belongs_to :user
end
And this is the create
method from my Appointments controller:
class AppointmentsController < ApplicationController
...
def create
@appointment = current_user.appointments.build(appointment_params)
@address = @appointment.addresses.build(appointment_params[:addresses_attributes]["0"])
respond_to do |format|
if @appointment.save
format.html { redirect_to current_user, notice: 'Appointment was successfully created.' }
format.json { render :show, status: :created, location: current_user }
else
format.html { render :new }
format.json { render json: @appointment.errors, status: :unprocessable_entity }
end
end
end
...
private
def appointment_params
params.require(:appointment).permit(:appointment_date, :appointment_start_time, :appointment_end_time, :comments, :phone_number, addresses_attributes: [:user_id, :street_address, :street_address_optional, :city, :state, :zip_code, :primary])
end
end
And finally, this is my form in my view:
<%= form_for(@appointment, :url => {:controller => "appointments", :action => "create"}, :html => {"data-abide" => ""}) do |f| %>
<label>
Appointment Date
</label>
<%= f.date_select :appointment_date %>
<label>
Appointment Timeframe Start
</label>
<%= f.time_select :appointment_start_time %>
<label>
Appointment Timeframe End
</label>
<%= f.time_select :appointment_end_time %>
<%= f.fields_for :addresses do |builder| %>
<%= builder.hidden_field :user_id, :value => current_user.id %>
<label>
Street Address
<%= builder.text_field :street_address %>
</label>
<label>
Street Address (Optional)
<%= builder.text_field :street_address_optional %>
</label>
<label>
City
<%= builder.text_field :city %>
</label>
<label>
State
<%= builder.text_field :state %>
</label>
<label>
Zip Code
<%= builder.number_field :zip_code %>
</label>
<%= builder.check_box :primary %><%= builder.label :primary %>
<% end %>
<label>
Special Instructions
<%= f.text_area :comments %>
</label>
<%= f.submit "Sign Up", :class => "button expand"%>
<% end %>
Thanks in advance for the help :)
Upvotes: 4
Views: 3304
Reputation: 4633
A user can have many appointments, but each one is in one address. (unless he can multilocate himself).
So you should do:
class User
has_many :appointments
class Appointment
has_one :address
class Address
belongs_to :appointments
If you want to retrieve the addresses in which the user has appointments you have to do:
@addresses = current_user.appointments.map {|app| app.address}
Upvotes: 4