montyreno
montyreno

Reputation: 21

How to set a form for nested attributes with collection selection?

I am trying to configure a form for nested attributes with a selector on RoR, but it seems I am doing it wrong.

I am trying to create a new affaire with nested_attributes contributions. Each contribution belongs to a skill which needs to be defined.

As there is a limited number of possible skills, I would like to have a selector in my form to select the contribution_skill from a list.

EDIT : I finally made it save the affaire with contributions by setting all the contribution attributes (I used the defaut set in the model definition). But I don't always want these attributes to be defined, so it is still not the solution. I add that there is no presence validation on these attributes. Anyone knows how to save a nested_attribute without all nested_attribute_attributes defined ?

Here is the models definitions :

class Affaire < ApplicationRecord
  has_many :contributions
  accepts_nested_attributes_for :contributions
end


class Skill < ApplicationRecord
  has_many :contributions
end

class Contribution < ApplicationRecord
  belongs_to :skill
  belongs_to :affaire
end

Controller definition :

def new
    @affaire = Affaire.new
    2.times {@affaire.contributions.build}
end

def create
    @affaire = Affaire.new(affaire_params)
    @affaire.save
    redirect_to @affaire
end

private
    def affaire_params
      params.require(:affaire).
        permit(:nam, contributions_attributes: [:id, :skill_id])
    end

View definition :

<%= form_with model: @affaire do |form| %>
    <%= form.label :name, "Name of Affaire" %>
    <%= form.text_field :name %>

    <%= form.fields_for :contributions do |ff| %>
        <%= ff.label :skill_id, "Contribution" %>
        <%= ff.collection_select(:skill_id, Skill.all, :id, :name) %>
    <% end %>

<%= form.submit "Create affaire" %>

I am expecting to get my affaire created with my contribution and the contribution to have its skill set. Unfortunately, it goes wrong.

Here iswhat I got in the rails server console :

Started GET "/affaires/new" for ::1 at 2019-09-04 21:06:41 +0200
Processing by AffairesController#new as HTML
  Rendering affaires/new.html.erb within layouts/application
  Skill Load (0.4ms)  SELECT "skills".* FROM "skills"
  ↳ app/views/affaires/new.html.erb:30
  CACHE Skill Load (0.0ms)  SELECT "skills".* FROM "skills"
  ↳ app/views/affaires/new.html.erb:30
  Rendered affaires/new.html.erb within layouts/application (20.9ms)
Completed 200 OK in 105ms (Views: 70.3ms | ActiveRecord: 2.2ms)


Started POST "/affaires" for ::1 at 2019-09-04 21:06:48 +0200
Processing by AffairesController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"GCc2wX2C7mWn77eksjdhDp5i1lFoUc2L3MLkOIXmWhavNdxwIynpNTVaRmbrvkKNdRtQxqoXjaInI2MaJtvvFA==", "affaire"=>{"name"=>"test",  "contributions_attributes"=>{"0"=>{"skill_id"=>"3"}, "1"=>{"skill_id"=>"1"}}}} (0.3ms)  BEGIN
  ↳ app/controllers/affaires_controller.rb:20
  Skill Load (0.3ms)  SELECT  "skills".* FROM "skills" WHERE "skills"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/affaires_controller.rb:20
  Skill Load (0.3ms)  SELECT  "skills".* FROM "skills" WHERE "skills"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/affaires_controller.rb:20
   (0.2ms)  ROLLBACK
  ↳ app/controllers/affaires_controller.rb:20
Redirected to http://localhost:3000/affaires
Completed 200 OK in 27ms (ActiveRecord: 2.8ms)

I can't see where is the problem. Parameters seems ok to me if I refer to rails documentation. I don't get why it rolls back.

Thanks for your help

Upvotes: 2

Views: 462

Answers (0)

Related Questions