Reputation: 7978
I have the following three models with relationships:
# category.rb
class Category < ActiveRecord::Base
has_many :category_marks
accepts_nested_attributes_for :category_marks
end
# category_mark.rb
class CategoryMark < ActiveRecord::Base
attr_accessible: :add, :stu, :inc
validates_presence_of :user_group
validates_presence_of :category_id
belongs_to :category
belongs_to :user_group
end
# user_group.rb
class UserGroup < ActiveRecord::Base
has_many :category_marks
end
category_marks
describe the access permissions of different user groups to different categories. I'm trying to create the category marks when I create a new category, hence the accepts_nested_attributes_for
. I'm able to edit categories and update category_marks at the same time, but not when I'm creating new category. This is my categories_controller.rb
(irrelevant bits removed):
class Admin::CategoriesController < ApplicationController
def new
@category = Category.new
@category.category_marks.build(UserGroup.all.map{|ug| { user_group: ug }})
respond_to do |format|
format.html # new.html.erb
format.json { render json: @category }
end
end
def edit
@category = Category.find(params[:id])
end
def create
@category = Category.new
@category.category_marks.build(UserGroup.all.map{|ug| { user_group: ug }})
@category.attributes = params[:category]
respond_to do |format|
if @category.save
format.html { redirect_to [:admin, :categories], notice: 'Category was successfully created.' }
format.json { render json: @category, status: :created, location: @category }
else
format.html { render action: "new" }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
def update
@category = Category.find(params[:id])
respond_to do |format|
if @category.update_attributes(params[:category])
format.html { redirect_to [:admin, :categories], notice: 'Category was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
end
Every category needs a category mark for every user group, so in the new
action I'm building a category marks object and association for every user group onto my new @category
object. This works fine and enables me to display the form fields for each category mark using a nested form. The difficulty I'm now having is getting those category marks to save in the create
action.
params
comes into create
like:
{"utf8"=>"✓",
"authenticity_token"=>"0rNpYy7OB+DPuzmu8HoxX2MvTnkjUyU+Vej+a4RMh7s=",
"category"=>{
"name"=>"test category",
"color"=>"#00f",
"parent_id"=>"3",
"category_marks_attributes"=>{
"0"=>{
"stu"=>"1",
"inc"=>"0",
"add"=>"1"},
"1"=>{
"stu"=>"0",
"inc"=>"1",
"add"=>"1"}}},
"button"=>"",
"action"=>"create",
"controller"=>"admin/categories"}
View code for the form:
<%= form_for([:admin, @category]) do |category_form| %>
<ul>
<li><%= category_form.label :name %> <%= category_form.text_field :name %></li>
<li><%= category_form.label :color %> <%= category_form.text_field :color, class: :add_colour_picker %></li>
<li><%= category_form.label :parent_id, "Parent category" %> <%= category_form.select :parent_id, Category.roots.delete_if{|c| c == @category}.map{|c| [c.name, c.id]}, include_blank: true %></li>
<br />
<h2>User Group Permissions</h2>
<table>
<tr>
<th>User Group</th>
<th>View Students</th>
<th>View Incidents</th>
<th>Add Incidents</th>
</tr>
<%= category_form.fields_for :category_marks do |category_marks_form| %>
<%= category_marks_form.hidden_field :user_group_id, value: category_marks_form.object.user_group_id %>
<tr>
<td><%= category_marks_form.object.user_group.name %></td>
<td><%= category_marks_form.check_box :stu %></td>
<td><%= category_marks_form.check_box :inc %></td>
<td><%= category_marks_form.check_box :add %></td>
</tr>
<% end %>
</table>
<li><%= button_tag "Save Category" %></li>
</ul>
<% end %>
Upvotes: 1
Views: 169
Reputation: 2228
Your category_marks_attributes
in params
are missing the user_group_id
and therefore would not validate or save based on the user input.
You probably need to add something like the following to your view:
= category_marks_builder.hidden_field :group_id, value: category_marks_builder.object.group_id
Also, I'm pretty sure it works as you have it, but I would get rid of the @category.attributes=
line and call @category.update_attributes params[:category]
instead of @category.save
.
Lastly, I'm not sure why you're doing the @category.category_marks.build
call again in the create
controller. I think this is going to give you two sets of category_marks
. One with the user inputs and one with default values.
I hope it helps.
Upvotes: 2