bennacer860
(rafik bennacer)
September 23, 2013, 4:48pm
1
This is the next episode in the saga, implementing a many-to-many relationship that started here ( How to implement a has many and belongs to many association in rails - #2 by djcp - Ruby on Rails - thoughtbot )
after struggling with my DB schema implementation and with help form the awesome thoughtbot people i finally got this to work
class Person < ActiveRecord::Base
attr_accessible :alignment, :gender, :source, :ethnicity, :description, :first_name, :last_name , :profession_ids
has_many :roles
has_many :organizations, through: :roles
has_many :positions, through: roles
accepts_nested_attributes_for :roles
end
class Role < ActiveRecord::Base
belongs_to :person
belongs_to :organization
belongs_to :position
end
class Organization < ActiveRecord::Base
has_many :roles
has_many :people, through: roles
end
class Position < ActiveRecord::Base
has_many :roles
has_many :people, through: roles
end
What i want to do now, is to create a form that will enter roles with organization and positions that already exist.
<%= simple_form_for @person do |f| %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<%= f.input :alignment , collection: ['democrate','republican','neutral'], include_blank: false %>
<%= f.input :gender , collection: ['male','female'], include_blank: false %>
<%= f.input :ethnicity, collection: ['white','african-american','asian-american'], include_blank: false %>
<%= f.simple_fields_for :roles do |p| %>
<%= p.input :organizations,
collection: Organization.all,
:label_method => lambda { |organization| "#{organization.name}"},
:input_html => {:class => 'chosen-select'} %>
<% p.input :positions %>
<% end %>
<%= f.button :submit %>
<% end %>
it seems like the simple_field_for is not displaying anything, how do i get this to work?
cpytel
(Chad Pytel)
September 23, 2013, 5:00pm
2
simple_fields_for
is going to iterate over the roles that are already on the user. If the user has no roles, nothing will be there.
If the user doesn’t have any roles (or, if you always want an additional one that could be created), you’re going to want to populate the roles of the user with a new, blank role that can be used for creation of a new role.
cpytel
(Chad Pytel)
September 23, 2013, 5:20pm
3
Also, just looking at your code again… You may want to do:
<%= f.simple_fields_for @person.roles do |p| %>
I’m not sure that that will help, but give it a try.
Also, I recommend you don’t use f
and p
as your variables. I recommend you use form
and person_form
to increase readability.
bennacer860
(rafik bennacer)
September 23, 2013, 6:56pm
4
i am getting this error now, it seems like it is not able to create a role object:
cpytel
(Chad Pytel)
September 23, 2013, 7:02pm
5
@rafikrafik Do you see how the error is “Organization expected, got String” this is exactly the error. It is expecting an Organization and and its being given a String.
Take a look at your params
. See how its just an organization
field? I’d expect this to be organization_id
and for the value to be the id of the selected organization.
bennacer860
(rafik bennacer)
September 23, 2013, 7:32pm
6
changing it to organization_id and position_id, fixed the problem of updating a Person.
I still can add a new Role though nor delete one.
bennacer860
(rafik bennacer)
September 24, 2013, 3:28pm
7
I am going to answer to my questions, to add person.
in the controller you need to have:
# GET /people/new
# GET /people/new.json
def new
@person = Person.new
@person.roles.build
....
and to delete you would have something like this:
<%= f.simple_fields_for :roles do |p| %>
<%= p.input :organization_id,
collection: Organization.all,
:label_method => lambda { |organization| "#{organization.name}"},
:input_html => {:class => 'chosen-select'} %>
<%= p.input :position_id,
collection: Position.all,
:label_method => lambda { |organization| "#{organization.name}"},
:input_html => {:class => 'chosen-select'} %>
<%= p.input :active ,collection: ['true','false'] , include_blank: false %>
Delete:<%= p.check_box :_destroy %>
<hr>
<% end %>