Reputation: 453
I'm new to RoR. My question is about updating associated Active Model's attr.
class User
has_many :toys
end
class Toy
belongs_to :user
end
and I have a page with a form of user where I can update user's attributes, and also certain attributes of associated user_devices:
<%= f.text_field :age %> # from user
<%= f.text_field :email %> # from user
....
<%= f.check_box :is_new %> # from toy!!
When I post the form and update all the attributes using update_attributes(), it shows "ActiveModel::MassAssignmentSecurity::Error"
@user.update_attributes(params[:user]) # it gives ActiveModel::MassAssignmentSecurity::Error
Another problem is, I don't know how to name the "is_new" attribute as it's in toy table.. Should it be :toys_is_new?
I want the associated toy's attributes to be updated as well. Can you help me with this?
Upvotes: 2
Views: 60
Reputation: 4653
You have to use Strong Parameters. It was introduced in Rails 4.
Example:
You have a model User
with id
, firstname
, lastname
, email
. The user should only be able to update the first and lastname.
Your View:
<%= form_for @user do |f| %>
<%= f.text_field :firstname %>
<%= f.text_field :lastname %>
<%= f.submit %>
<% end %>
Your Controller:
before_action :set_user
def edit
end
def create
if @user.update user_params
# Set success message
# redirect to proper site
else
# Set error
render :edit
end
end
private
def set_user
@user = User.find(params[:id]) # Rescue against ActiveRecord::RecordNotFound error
end
def user_params
params.require(:user).permit(:firstname, :lastname) # Here the strong parameters stuff happens
end
If you want to permit more parameters you just have to add them to the permit
method call.
You got this error just for security reasons.
You can disable Strong Parameters with config.action_controller.permit_all_parameters = true
but I highly recommend you to use this feature.
Upvotes: 0
Reputation: 76774
Because is_new?
is from Toy
, you have to use accepts_nested_attributes_for
:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :toys
accepts_nested_attributes_for :toys
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def edit
@user = User.find params[:id]
end
def update
@user = User.find params[:id]
@user.update user_params
end
private
def user_params
params.require(:user).permit(:age, :email, toys_attributes: [:is_new])
end
end
To get this to work in the view
, you'll need to use the fields_for
helper:
#app/views/users/edit.html.erb
<%= form_for @user do |f| %>
<%= f.fields_for :toys, @user.toys do |t| %>
<%= t.object.name %>
<%= t.check_box :is_new %>
<% end %>
<%= f.submit %>
<% end %>
Upvotes: 1