Search code examples
ruby-on-railsrubynestedsimple-formcocoon-gem

Cocoon Show object instead value


My situation:

"app/models/aircraft.rb"

class Aircraft < ActiveRecord::Base
  has_many :aircraft_crew_roles
  has_many :crew_roles, through: :aircraft_crew_roles, class_name: 'CrewRole'
end

"app/models/aircraft_crew_role.rb"

aircraft_id
crew_role_id

class AircraftCrewRole < ActiveRecord::Base
  belongs_to :aircraft
  belongs_to :crew_role
  accepts_nested_attributes_for :crew_role, reject_if: :all_blank
end

"app/models/crew_role.rb"

name

class CrewRole < ActiveRecord::Base
end

"app/views/aircrafts/_form.html.haml"

= simple_form_for(@aircraft) do |f|
  = f.error_notification
  = f.input :name
  #crew
    = f.simple_fields_for :aircraft_crew_roles do |cr|
      = render 'aircrafts/aircraft_crew_role', :f => cr
    = link_to_add_association 'add a Crew Role', f, :aircraft_crew_roles, partial: "aircrafts/aircraft_crew_role"

  = f.button :submit

"app/views/aircrafts/_aircraft_crew_role.html.haml"

.nested-fields.crew-fields
  #crew_from_list
    = f.association :crew_role, as: :select, collection: CrewRole.all()
  = link_to_add_association 'or create a new Role', f, :crew_role
  = link_to_remove_association "remove Role", f

"app/views/aircrafts/_crew_role_fields.html.haml"

.nested-fields
  = f.input :role

this is my current situation and almost everything work fine: I can add new crew members to the aircraft and this will create the corresponding entry in the aircraft_crew_role and crew_role tables and if I connect to the database I can see that all the entry are right ( I see all ID and the role in the crew_role table is the one I've used in the form) but if I try use the crew already saved with the previous aircraft the select is populated with object instead of string:

#<CrewRole:0x007fa90d2f8df8>
#<CrewRole:0x007fa90d2f8c90>
#<CrewRole:0x007fa90d2f8b28>

I've already used cocoon in many other places in the app and in all the other places it worked smoothly. I've compared my code with the example on the cocoon repo but I can't find the problem


Solution

  • You are using simple_form's f.association which will try to guess how to present the CrewRole object. It looks for name, label or plain old to_s ... In your case it is a non-standard field role, so it will just convert the model to string (giving the result you got).

    To solve this you would have to rename your column (a bit drastic, but maybe that is what you did when recreating the db?) or better, write something like

    = f.association :crew_role, label_method: :role
    

    See simple_form documentation for more info.