Reputation: 303
I have a model with nested attributes. I can't get collection_select
to work. Here's what I have
class Client < ActiveRecord::Base
belongs_to :contact
belongs_to :person, dependent: :destroy
accepts_nested_attributes_for :person, allow_destroy: true
end
class Contact < ActiveRecord::Base
has_many :clients
belongs_to :person, dependent: :destroy
accepts_nested_attributes_for :person, allow_destroy: true
end
class Person < ActiveRecord::Base
has_one :client
has_one :contact
belongs_to :personal_title
# Returns the combined personal title, first and surname
def name
[
personal_title.nil? ? '' : personal_title.title,
first_name || '',
last_name || ''
].reject(&:empty?).join(' ')
end
end
In summary, Client
has a contact_id
and a person_id
, Contact
has a person_id
and Person
has a personal_title_id
. On my form I have
<div class="field">
<%= f.label :contact_id %><br>
<%= f.collection_select(:contact_id, Client.all, :id, :name,
{include_blank: true}) %>
</div>
I know where the problem is, but from the documentation I can't work out how to fix it. The error I get is undefined method 'name' for #<Client:0x6c01350>
. That's correct. name() is declared in Person, not Client. I can get it to work with,
<select name="client[contact_id]">
<% Contact.all.each do |contact| %>
<option value="<%= contact.id %>"><%= contact.person.name %></option>
<% end %>
</select>
This works because I have used contact.person.name
, not contact.name
.
Upvotes: 1
Views: 408
Reputation: 1023
In the model Client isnt a method to return the name. The method to return the name is in the Person class.
Create a method in Client to return the name of the person and it should be work.
class Client < ActiveRecord::Base
belongs_to :contact
belongs_to :person, dependent: :destroy
accepts_nested_attributes_for :person, allow_destroy: true
def name
self.person.name
end
end
Upvotes: 1