Ajith
Ajith

Reputation: 345

unpermitted attributes even after whitelisting in rails 5

project details -> rails 5.1 and ruby 2.4.1

I'm trying to create a simple todo app. my problem is with nested model forms. if i create a project without any task and i save it. then if i want to edit the project and add some tasks, tasks fields are not showing up. If i add tasks while creating the projects everything works as expected.in edit page i can see both project and tasks and i can edit as well.

below are my 2 models. I didnt use nested routes. just using the nested model forms.

class Project < ApplicationRecord
   has_many :tasks, inverse_of: :project, dependent: :destroy
   validates :name, presence: :true
   validates :description, presence: :true
   accepts_nested_attributes_for :tasks, reject_if: proc { |attributes| attributes[:name].blank? }
end

class Task < ApplicationRecord
   belongs_to :project, inverse_of: :tasks
end

Below is my _form partial for new and edit.

<%= form_for @project do |form| %>
        <% if @project.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:</h2>
          <ul>
          <% @project.errors.full_messages.each do |message| %>
            <li><%= message %></li>
          <% end %>
          </ul>
        </div>
      <% end %>

      <div class="field">
        <%= form.label :name %>
        <%= form.text_field :name, id: :project_name %>
      </div>

      <div class="field">
        <%= form.label :description %>
        <%= form.text_field :description, id: :project_description %>
      </div>

      <%= form.fields_for :tasks do |task_form| %>
        <div class="field">
          <%= task_form.label :task_name %>
          <%= task_form.text_field :name, id: :task_name %>
        </div>
        <div class="field">
          <%= task_form.label :task_description %>
          <%= task_form.text_field :description, id: :task_description %>
        </div>
      <% end %>

      <div class="actions">
        <%= form.submit  %>
      </div>
<% end %>

white listing of the project controller is given below.

 def project_params
   params.require(:project).permit(:name, :description, tasks_attributes: [:id, :name, :description])
 end

Any help is appreciated -Ajith

Upvotes: 0

Views: 59

Answers (1)

Jay-Ar Polidario
Jay-Ar Polidario

Reputation: 6603

if i create a project without any task and i save it. then if i want to edit the project and add some tasks, tasks fields are not showing up.

... is how it is actually supposed to be. So your problem most likely is not related to Strong Parameters problem, as I do not see any obvious problems in your view file and your project_params method. Now since you don't want that this behaviour, you'll probably want something like the following which builds up 1 or more task objects by default if there's no task object associated to theproject yet, so that there will always be at least one group of task fields when you're creating or editing a project.

app/controllers/projects_controller.rb

class ProjectsController < ApplicationController
  def new
    @project = Project.new
    @project.tasks.build
    # the above code just above is the same as below
    # @project.tasks << Task.new

    # now you can call this again like below, if you want 2 groups of `tasks` fields when you're creating a Project
    @project.tasks.build
  end

  def edit
    @project = Project.find(params[:id])

    # this project may not yet have a `Task` object associated to it; if so we build a `Task` object like so
    # this builds 3 `Task` objects; you can just use one below if you just want to show one in your edit form.
    if @project.tasks.count == 0
      @project.tasks.build
      @project.tasks.build
      @project.tasks.build
    end
  end
end

P.S. you may be interested in cocoon gem if you want to have a form that can build dynamic nested attributes automatically for you (like for example you want 2 buttons like the following) '(Add more task)' and '(Remove this task)`

Upvotes: 1

Related Questions