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.
Related
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.
I am working with Rails 4, Active Admin and Paperclip to setup a has_many images association. When generating my has_many portion of the form I keep getting errors. Currently I am getting
undefined method `+' for nil:NilClass. Here is my code:
news model
class News < ActiveRecord::Base
validates :body, presence: true
validates :title, presence: true, length: { maximum: 140 }
has_many :news_images, dependent: :destroy
end
News image model
class NewsImage < ActiveRecord::Base
belongs_to :news
has_attached_file :photo, styles: {
small: "150x150>",
medium: "300x300>",
large: "600x600>"
}
validates_attachment_presence :photo
validates_attachment_size :photo, less_than: 5.megabytes
end
admin code
ActiveAdmin.register News do
index do
column :title
default_actions
end
form multipart: true do |f|
f.semantic_errors *f.object.errors.keys
f.inputs "News Details" do
f.input :title
f.input :body, :as => :rich
end
f.has_many :news_images do |p|
end
f.actions
end
controller do
def permitted_params
params.permit news: [:title, :body, news_images: [:photo]]
end
end
end
Ideally I would like the user to be able to upload multiple images to the form. Any one have experience with this issue?
The stack trace is saying insert_tag renderer_for(:new) which is being tripped on f.has_many :news_images do |p|
So the problem was with the news model. I thought accepts_nested_attributes_for was deprecated with the addition of strong params but I guess I was wrong adding this to the news model fixed my issue
accepts_nested_attributes_for :news_images,
:reject_if => lambda { |attributes| attributes[:photo].blank? },
:allow_destroy => true
There was another bug in Paperclip 4.1 that was fixed recently: https://github.com/thoughtbot/paperclip/issues/1457
I spent a ton of time tracking this down, but finally was able to find the connection between formtastic and paperclip 4.1.
The solution that worked for me was to switch to paperclip's master branch in my Gemfile as follows:
gem 'paperclip', github: 'thoughtbot/paperclip'
Model order.rb
class Order < ActiveRecord::Base
attr_accessible :address, :email, :name, :payment_type_id
belongs_to :payment_type
PAYMENT_TYPES = PaymentType.pluck(:id)
validates :name, :address, :email, :payment_type_id, :presence => true
validates :payment_type_id, :inclusion => {:in => PAYMENT_TYPES}
end
Model payment_type.rb
class PaymentType < ActiveRecord::Base
attr_accessible :name, :id
has_many :order
end
From browser, validation works fine, if it is wrong it give an error, else go forward.
But problem is when I run rake test:functionals from terminal. Test didn't pass the validation. If I comment this line:
validates :payment_type_id, :inclusion => {:in => PAYMENT_TYPES}
all is ok. I don't understand why it is working in one plase, but in tests not ? ...
Fixtures are all ok.
Please help.
Most likely the problem is, that you are storing your payment types in a constant.
For your tests to work, the PaymentTypes have to be available in the database before rails loads your Order model, and this might not be the case.
One way to get around this, would be to use a (memoized) class method to store your payment types. As long as you access this class method after all your PaymentTypes are in the database, you should be fine.
class Order < ActiveRecord::Base
validates :payment_type_id, :inclusion => { :in => self.payment_types }
def self.payment_types
##payment_types ||= PaymentType.pluck(:id)
end
end
In my controller, I've got error when create action and try create model [can't mass-assignment], but
in my spec, my test of mass-assignment model its pass!?!
My Model:
class Customer < ActiveRecord::Base
attr_accessible :doc, :doc_rg, :name, :birthday, :name_sec, :address, :state_id, :city_id, :district_id,
:customer_pj, :is_customer, :segment_id, :activity_id, :person_type, :person_id
belongs_to :person , :polymorphic => true, dependent: :destroy
has_many :histories
has_many :emails
def self.search(search)
if search
conditions = []
conditions << ['name LIKE ?', "%#{search}%"]
find(:all, :conditions => conditions)
else
find(:all)
end
end
end
I`ve tired set attr_accessible in controller too, in my randomized way.
the Controller:
class CustomersController < ApplicationController
include ActiveModel::MassAssignmentSecurity
attr_accessible :doc, :doc_rg, :name, :birthday, :name_sec, :address, :state_id, :city_id, :district_id, :customer_pj, :is_customer
autocomplete :business_segment, :name, :full => true
autocomplete :business_activity, :name, :full => true
[...]
end
The test, my passed test
describe "accessible attributes" do
it "should allow access to basics fields" do
expect do
#customer.save
end.should_not raise_error(ActiveModel::MassAssignmentSecurity::Error)
end
end
The error:
ActiveModel::MassAssignmentSecurity::Error in CustomersController#create
Can't mass-assign protected attributes: doc, doc_rg, name_sec, address, state_id, city_id, district_id, customer_pj, is_customer
https://github.com/megabga/crm
1.9.2p320
Rails 3.2
MacOS
pg
my bad, in my controller its setting an oldest class. Then old class don`t have attributes passing in parameters. Sorry!
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