I am using Rails 3.2.14, inherited_resource and strong_parameter gem.I just followed Strong Parameters in Rails 3.2.8 steps but i am getting error like below,
Can't mass-assign protected attributes:content, title, nature_bien_id, nature_transaction_id, nbr_chambres, nbr_pieces, section_id, city, zip, surface_habitable, surface_terrain
My code in controller is like that
def create
#mandat = current_user.mandats.new(mandats_params)
end
private
def annonce_params
params.require(:annonce).permit(:created_at, :description, :image, :dpe, :nature_bien_id, :nature_transaction_id,:nbr_chambres, :nbr_pieces, :prix_net_acquereur, :section_id, :surface_habitable,:surface_terrain, :titre, :annonce_images_attributes, :user_id, :ville, :zip, :reference,:available_time, :is_valid, :close, :reasonclosing, :annonce_support_ids, :equipement_ids)
end
Thanks for in advance
You have to turn off attributes protection in your config/application.rb:
config.active_record.whitelist_attributes = false
Please check that all attributes that you want to updated are listed in the attr_accessible definition in your Mandat model:
attr_accessible :created_at, :description, :image, :dpe, :nature_bien_id,
:nature_transaction_id,:nbr_chambres, :nbr_pieces, :prix_net_acquereur,
:section_id, :surface_habitable,:surface_terrain, :titre,
:annonce_images_attributes, :user_id, :ville, :zip, :reference,
:available_time, :is_valid, :close, :reasonclosing, :annonce_support_ids,
:equipement_ids
In my rails project,I use audited Gem.Refer Audited gem using strong Parameter.So in my model
Change
class Mandat < ActiveRecord::Base
audited on: [:update]
to
class Mandat < ActiveRecord::Base
audited :allow_mass_assignment => true,on: [:update]
then it will works perfectly.
Related
I have a devise model that has a nested form (supp_form is the nested object) on sign up. When I submit the form I am getting the following error:
WARNING: Can't mass-assign protected attributes for Business: supp_form_attributes, terms_of_service
app/controllers/businesses/registrations_controller.rb:11:in `create'
I am using the nested_form gem and it seems as if my form is passing field data through to the console. My parameters after submit look like the following:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"XXX", "business"=>{"type"=>"Business", "supp_form_attributes"=>{"title"=>"mr.", "first_name"=>"jane", "last_name"=>"doe", "mobile_phone_number"=>"94034903", "loan_agreement_authorization"=>"1", "work_phone_number"=>"49034903", "business_industry"=>"Natural Resources and Mining", "legal_structure"=>"Sole Proprietorship", "employee_count"=>"5 to 10", "years_in_business"=>"5+ years", "business_address"=>"72 pentland rd", "business_city"=>"Waterdown", "business_postal_code"=>"l0r2h5", "business_province"=>"ON"}
business.rb
class Business < User
# Associations
has_one :supp_form
has_many :loan_applications
has_many :transactions
# Nested attributes
accepts_nested_attributes_for :supp_form, :loan_applications
# After save action
after_save :create_account
# Validations
validates_acceptance_of :terms_of_service
validate :terms_of_service, presence: true
end
supp_form.rb
class SuppForm < ActiveRecord::Base
# Associations
belongs_to :business
# Validations
validates_acceptance_of :terms
validates :business_id, :first_name, :last_name, :work_phone_number, :business_address, :business_postal_code, :business_city, presence: true
end
registraionts_controller.rb
class Businesses::RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params
def new
build_resource({})
resource.build_supp_form
respond_with self.resource
end
def create
super
resource.update_attribute(:railsid, '%010d' % rand(10 ** 10))
end
private
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, :type, :confirmed_at, :business_name, :terms, :railsid, :terms_of_service,
supp_form_attributes: [:business_id, :title, :loan_agreement_authorization, :first_name,
:last_name, :work_phone_number, :business_address, :business_postal_code,
:business_city, :business_name, :years_in_business, :legal_structure,
:business_industry, :employee_count, :mobile_phone_number, :business_province])}
end
def after_sign_up_path_for(resource)
business_root_path
end
end
supp_forms_controller.rb
class SuppFormsController < ApplicationController
before_filter :authenticate_user!
def new
#suppform = SuppForm.new(supp_form_params)
end
def create
#suppform = SuppForm.create(supp_form_params)
end
private
def supp_form_params
params.require(:supp_form).permit(:business_id, :title, :loan_agreement_authorization, :first_name,
:last_name, :work_phone_number, :business_address, :business_postal_code,
:business_city, :business_name, :years_in_business, :legal_structure,
:business_industry, :employee_count, :mobile_phone_number, :business_province)
end
end
You are using Rails 4 with strong parameters. And you get an error triggered by the protected_attributes gem (or default rails 3 app).
With strong_parameters on place you can remove safety the protected_attributes gem. And remove the configuration if you have it (config.active_record.whitelist_attributes).
I'm trying to systematically upgrade from rails 3 to rails 4 and all of my 25 models are based on attr_accessor! So before getting into that can anyone provide me a simple example on how to do this. I've read the documentation and other topics but it's not clear on how to do it since this is my first upgrade Rodeo.
class Settings < ActiveRecord::Base
image_accessor :favicon
attr_accessible :company_name, :show_hot_jobs, :show_students, :subheading, :show_testimonials, :show_on_boarding, :max_concurrent_applications
attr_accessible :image_uid, :max_concurrent_application_groups
attr_accessible :primary_color, :white_color, :gray_color, :opacity, :locale, :lang_nl, :lang_fr, :lang_de, :lang_en, :privacy_page
attr_accessible :show_evp, :show_contact_person, :show_jobs_for_you
attr_accessible :favicon, :favicon_uid, :remove_favicon, :retained_favicon
attr_accessible :home_url, :show_correspondence, :show_appointment
attr_accessible :sliderone_uid, :slidertwo_uid, :sliderthree_uid, :sliderfour_uid, :sliderfive_uid
attr_accessible :sliderone_link, :slidertwo_link, :sliderthree_link, :sliderfour_link, :sliderfive_link
attr_accessible :sliderone_testoverview, :slidertwo_testoverview, :sliderthree_testoverview, :sliderfour_testoverview, :sliderfive_testoverview
attr_accessible :sliderone_page, :slidertwo_page, :sliderthree_page, :sliderfour_page, :sliderfive_page
validate :any_lang_present?
validates :max_concurrent_applications, :numericality => { :greater_than_equal_to => 1 }
validates :max_concurrent_application_groups, :numericality => { :greater_than_equal_to => 1 }
# Fav Icon Validation
validates_property :ext, of: :favicon, :in => ['ico', 'png', 'gif']
has_paper_trail
has_many :setting_translations, :foreign_key => :setting_id
accepts_nested_attributes_for :setting_translations, :allow_destroy => true, :reject_if => :all_blank
attr_accessible :setting_translations_attributes, :allow_destroy => true
translates :subheading, :company_name, :image_uid, :home_url, :sliderone_uid, :slidertwo_uid, :sliderthree_uid, :sliderfour_uid, :sliderfive_uid
translates :sliderone_link, :slidertwo_link, :sliderthree_link, :sliderfour_link, :sliderfive_link
translates :sliderone_testoverview, :slidertwo_testoverview, :sliderthree_testoverview, :sliderfour_testoverview, :sliderfive_testoverview
translates :sliderone_page, :slidertwo_page, :sliderthree_page, :sliderfour_page, :sliderfive_page
attr_accessible can be converted like so:
From
class Settings
attr_accessible :home_url
accepts_nested_attributes_for :setting_translations
end
class SettingTranslation
attr_accessible :etc
end
To
class SettingsController
def create
#settings = Settings.new(settings_params)
# ...
end
private
def settings_params
params.require(:settings).permit(
:home_url,
:setting_translations_attributes => [:id, :_destroy, :etc]
)
end
end
Note, you have to include :_destroy if you want to allow destroy on that model (:allow_destroy => true), and you have to include all attributes that should be accessible from any nested attributes. Though you remove attr_accessible when you've permitted, you do not remove accepts_nested_attributes_for.
Just remove attr_accessible from model. and add permit params according to need in controller.
like below :
class SupportTicketsController < ApplicationController
def create
#support_ticket = SupportTicket.create(house_params)
......
end
private
def house_params
params.require(:support_ticket).permit(:subject, :message, ....)
end
end
and if you don't want to make this much changes then add "protected_attributes" gem https://github.com/rails/protected_attributes in your gemfile And everything would work as before.
Has anyone else run into a mass assignment error when trying to create a new piano?
ActiveModel::MassAssignmentSecurity::Error in Refinery::Pianos::Admin::PianosController#create
Can't mass-assign protected attributes: name, dimensions, manufactured_on(1i), manufactured_on(2i), manufactured_on(3i), upright, photo_id, description, position
If you open up your model file and put this in there you will have more success:
attr_accessible :dimensions, :manufactured_on, :upright, :photo_id, :description, :position
The model file should look like this:
module Refinery
module Pianos
class Piano < Refinery::Core::BaseModel
self.table_name = 'refinery_pianos'
attr_accessible :dimensions, :manufactured_on, :upright, :photo_id, :description, :position
acts_as_indexed :fields => [:dimensions, :description]
validates :dimensions, :presence => true, :uniqueness => true
belongs_to :photo, :class_name => '::Refinery::Image'
end
end
end
Hope that helps. I guess it's a bug in the version you're using but it's fixed in the Refinery CMS 2-0-stable branch.
I have 2 models. Member and Survey
member.rb as follows
Class Member < ActiveRecord::Base
has_one :survey, :dependent => :destroy
accepts_nested_attributes_for :survey
attr_accessible :fname,:lname, :address, :city, :state, :zip, :email, :phone, :phone_alt, :e_contact, :e_contact_phone, :physician, :physician_phone, :chiropractor, :chiropractor_phone, :password, :password_confirmation, :remember_me, :survey_attributes
end
survey.rb as follows
Class Survey < ActiveRecord::base
belongs_to :member
end
however, whenever I try to create the member with the survey attributes I receive
ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: surveys
I am testing this via the console.
With a has_one association the accessible call should read:
attr_accessible :survey_attributes
The params you're posting need to be nested, like so:
params = { :member => { :name => 'Jack', :survey_attributes => { :attribute => 'value' } } }
In the form make sure that you're building the nested relationship correctly, ie. you must use:
= form_for #member do |f|
...
= f.fields_for :survey do |s|
...
If you have those things setup like so it should work. If this isn't catching your error then please show a log of what you're trying in the console and isn't working.
See #accepts_nested_attributes_for in the Rails API for more info.
In many of my rails models, I have a number of fields which are what I think of as "normal" model attributes, ie things which are set by the user, then later displayed, and are mandatory parts of a model instance. It seems kind of overly verbose to have to always do this:
class Person < ActiveRecord::Base
attr_accessible :name
attr_accessible :age
attr_accessible :height
validates :name, :presence => true
validates :age, :presence => true
validates :height, :presence => true
end
Ideally I'd like to just tell rails "everything but the auto-generated ID field should be validated present and accessible for mass assignment". How can I do that, given that it's said to be bad security practice to just make everything available for mass assignment?
Update: The existing way also seems bad in that I type my list of attributes twice, which is quite error prone.
Define your own class method, say on ActiveRecord::Base:
class ActiveRecord::Base
def self.validate_presence_and_make_accessible *args
attr_accessible *args
validates_presence_of *args
end
end
Then in your models:
class Person < ActiveRecord::Base
validate_presence_and_make_accessible :name, :age, :height
end
I suck at naming methods sometime, btw. Feel free to rename to something better.
A little less verbose way:
class Person < ActiveRecord::Base
attr_accessible :name, :age, :height
validates :name, :age, :height, :presence => true
end
Specifying only protected attributes:
class Person < ActiveRecord::Base
attr_protected :id
validates :name, :age, :height, :presence => true
end
This is simpler:
class Person < ActiveRecord::Base
attr_protected :id
validates_presence_of :name, :age, :height
end
And regarding your comment about security practice of mass assignments, I think you should read this: http://b.lesseverything.com/2008/3/11/use-attr_protected-or-we-will-hack-you