0
votes

I followed the answer given here to create a simple dynamic form (not nested). The idea is to invite several people with their email. Then I have an "Add Team Member" button to add the fields to enter the coworker email.

I get the following error but I don't know why:

ActiveModel::ForbiddenAttributesError in InvitationsController#create

The parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"zLs8DWkzO+bPc2jGhFptgc+BAGAwzr1kcn/hkX/6vQbQ/cDCzuqoGCMGUTcYHs+up7nBzHFiEXVcKustyL1KIA==",
 "invitation"=>[{"email"=>"[email protected]", "_destroy"=>"false", "user_id"=>"1"}, {"email"=>"[email protected]", "_destroy"=>"false", "user_id"=>"1"}],
 "commit"=>"Save Team Members"}

My create action and invitation_params in the controller:

def create
    puts params[:invitation].to_yaml
    params[:invitation].each do |invitation_params|
     Invitation.create(invitation_params)
    end
    redirect_to invitation_path
  end

def invitation_params
      params.require(:invitation).permit(:id, :email, :user_id, :_destroy, :token)
    end

My form:

<%= form_for(invitation) do |f| %>
  <% if invitation.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(invitation.errors.count, "error") %> prohibited this invitation from being saved:</h2>

      <ul>
      <% invitation.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div id="container_invitations"></div>

  <%= link_to "Add a New Team Member", add_invitation_path, :method => :post, :remote => true %>

  <div class="actions">
    <%= f.submit "Save Team Members", class: "cta2" %>
  </div>
<% end %>

add_invitation controller action (to add the fields dynamically):

def add_invitation
    respond_to do |format|
      format.js
    end
  end

add_invitation.js.erb:

$('#container_invitations').append("<%= escape_javascript(render :partial => 'invitation_fields_render') %>");
$('.remove_fields').on('click', function(e) {
  $(this).parent().remove();
});

_invitation_fields_render.html.erb (the partial with the fields)

<div class="new_invitation_row">
 <%= email_field_tag "invitation[][email]", nil, placeholder: "Team Member Email", :required => 'required' %>
 <%= hidden_field_tag "invitation[][_destroy]", nil, value: false %>
 <a class="remove-link remove_fields dynamic" href="#"><i class="fa fa-trash fa-lg" title="Remove"></i></a>
 <%= hidden_field_tag "invitation[][user_id]", nil, value: current_user.id %>
</div>

My invitation model:

class Invitation < ActiveRecord::Base
  has_secure_token

  belongs_to :user
end

Thank you.

UPDATE

I added the new params.permit line proposed by IngoAlbers. I still get the error. Here is the full stacktrace of the error:

Started POST "/invitations" for 127.0.0.1 at 2017-12-01 07:49:02 +0000 Processing by InvitationsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"pV5wQj3QHXksNEtJ8nZSjWDc8VyHiewVCt4A1+ijH8G5GIyNmgmOh8BBcrhuMvCiCOQw8MYlQAQkiwprX+To5w==", "invitation"=>[{"email"=>"[email protected]", "_destroy"=>"false", "user_id"=>"1"}], "commit"=>"Save Team Members"} User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]] CoreBot Load (0.2ms) SELECT "core_bots".* FROM "core_bots" WHERE "core_bots"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] Completed 500 Internal Server Error in 4ms (ActiveRecord: 0.6ms)

ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):
app/controllers/invitations_controller.rb:35:in block in create' app/controllers/invitations_controller.rb:34:ineach' app/controllers/invitations_controller.rb:34:in `create' Rendering /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout Rendering /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb Rendered /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (5.3ms) Rendering /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb Rendered /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.5ms) Rendering /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb Rendered /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.5ms) Rendered /Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (93.1ms)

1
Can you please try to set config.action_controller.action_on_unpermitted_parameters = :log in your environment file? (probably config/environments/development.rb). Then check and paste the logs again. We can see then on which parameters it fails.IngoAlbers
I added it in my environment file and updated the logs but it seems it's the same..nico_lrx
Are you sure you don't actually have it in the environment file with value :raise? If you are sure try restarting the server.IngoAlbers
I checked, it's :log, I restarted the server but still the same logs.nico_lrx
Ok I misinterpreted something here, think I got it now. Will update my answer.IngoAlbers

1 Answers

1
votes

The problem is that invitation is an array. So you actually need to permit the array in the invitation_params.

def invitation_params
  params.permit(invitation: [:id, :email, :user_id, :_destroy, :token])
end

In addition you have a problem in the create action itself. You don't actually use the permitted parameters, that was defined. It should probably look like this:

def create
  invitation_params[:invitation].each do |invitation|
    Invitation.create(invitation)
  end

  redirect_to invitation_path
end