Giter Site home page Giter Site logo

protected_attributes's Introduction

Protected Attributes

Build Status

Protect attributes from mass-assignment in Active Record models.

This plugin adds the class methods attr_accessible and attr_protected to your models to be able to declare white or black lists of attributes.

Note: This plugin will be officially supported until the release of Rails 5.0.

Installation

Add this line to your application's Gemfile:

gem 'protected_attributes'

And then execute:

bundle install

Usage

Mass assignment security provides an interface for protecting attributes from end-user injection. This plugin provides two class methods in Active Record classes to control access to their attributes. The attr_protected method takes a list of attributes that will be ignored in mass-assignment.

For example:

attr_protected :admin

attr_protected also optionally takes a role option using :as which allows you to define multiple mass-assignment groupings. If no role is defined then attributes will be added to the :default role.

attr_protected :last_login, :as => :admin

A much better way, because it follows the whitelist-principle, is the attr_accessible method. It is the exact opposite of attr_protected, because it takes a list of attributes that will be mass-assigned if present. Any other attributes will be ignored. This way you won’t forget to protect attributes when adding new ones in the course of development. Here is an example:

attr_accessible :name
attr_accessible :name, :is_admin, :as => :admin

If you want to set a protected attribute, you will have to assign it individually:

params[:user] # => {:name => "owned", :is_admin => true}
@user = User.new(params[:user])
@user.is_admin # => false, not mass-assigned
@user.is_admin = true
@user.is_admin # => true

When assigning attributes in Active Record using attributes= the :default role will be used. To assign attributes using different roles you should use assign_attributes which accepts an optional :as options parameter. If no :as option is provided then the :default role will be used.

You can also bypass mass-assignment security by using the :without_protection option. Here is an example:

@user = User.new

@user.assign_attributes(:name => 'Josh', :is_admin => true)
@user.name # => Josh
@user.is_admin # => false

@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :as => :admin)
@user.name # => Josh
@user.is_admin # => true

@user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
@user.name # => Josh
@user.is_admin # => true

In a similar way, new, create, create!, update_attributes and update_attributes! methods all respect mass-assignment security and accept either :as or :without_protection options. For example:

@user = User.new({ :name => 'Sebastian', :is_admin => true }, :as => :admin)
@user.name # => Sebastian
@user.is_admin # => true

@user = User.create({ :name => 'Sebastian', :is_admin => true }, :without_protection => true)
@user.name # => Sebastian
@user.is_admin # => true

By default the gem will use the strong parameters protection when assigning attribute, unless your model has attr_accessible or attr_protected calls.

Errors

By default, attributes in the params hash which are not allowed to be updated are just ignored. If you prefer an exception to be raised configure:

config.active_record.mass_assignment_sanitizer = :strict

Any protected attributes violation raises ActiveModel::MassAssignmentSecurity::Error then.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

protected_attributes's People

Contributors

aerlinger avatar agis avatar amatsuda avatar arie avatar arthurnn avatar asanghi avatar ashchan avatar betelgeuse avatar carlosantoniodasilva avatar edouard-chin avatar frodsan avatar fxn avatar guilleiguaran avatar jeroenvisser101 avatar jteneycke avatar jurgens avatar kaspth avatar matthewd avatar obrie avatar pacoguzman avatar patrickdavey avatar pixeltrix avatar pravi avatar rafaelfranca avatar robertomiranda avatar rst avatar senny avatar sgrif avatar t27duck avatar terceiro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

protected_attributes's Issues

`method_missing': undefined method `whitelist_attributes=' for ActiveRecord::Base:Class (NoMethodError)

  1. Create a new app with Rails 3.2.8
  2. Upgrade it to Rails 4:
# Gemfile
gem 'rails', github: 'rails/rails'
gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders'
gem 'journey', github: 'rails/journey'
  1. Add protected_attributes:
# Gemfile
gem 'protected_attributes', github: 'rails/protected_attributes'
  1. Attempt to run bundle exec rails console:
/Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activerecord/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `whitelist_attributes=' for ActiveRecord::Base:Class (NoMethodError)
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activerecord/lib/active_record/railtie.rb:96:in `block (3 levels) in <class:Railtie>'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activerecord/lib/active_record/railtie.rb:95:in `each'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activerecord/lib/active_record/railtie.rb:95:in `block (2 levels) in <class:Railtie>'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activesupport/lib/active_support/lazy_load_hooks.rb:38:in `instance_eval'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activesupport/lib/active_support/lazy_load_hooks.rb:38:in `execute_hook'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activesupport/lib/active_support/lazy_load_hooks.rb:28:in `block in on_load'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activesupport/lib/active_support/lazy_load_hooks.rb:27:in `each'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activesupport/lib/active_support/lazy_load_hooks.rb:27:in `on_load'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/activerecord/lib/active_record/railtie.rb:94:in `block in <class:Railtie>'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/railties/lib/rails/initializable.rb:30:in `instance_exec'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/railties/lib/rails/initializable.rb:30:in `run'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/railties/lib/rails/initializable.rb:55:in `block in run_initializers'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:150:in `block in tsort_each'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:183:in `block (2 levels) in each_strongly_connected_component'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:219:in `each_strongly_connected_component_from'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:182:in `block in each_strongly_connected_component'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:180:in `each'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:180:in `each_strongly_connected_component'
        from /Users/alindeman/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/tsort.rb:148:in `tsort_each'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/railties/lib/rails/initializable.rb:54:in `run_initializers'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/railties/lib/rails/application.rb:185:in `initialize!'
        from /Users/alindeman/.rvm/gems/ruby-1.9.3-p286/bundler/gems/rails-b1fe78e0cb81/railties/lib/rails/railtie/configurable.rb:30:in `method_missing'
        from /Users/alindeman/workspace/upgradedrails3app/config/environment.rb:5:in `<top (required)>'

Test failure: "uninitialized constant ActiveModel (NameError)"

The test/mass_assignment_security/* test cases fail such as:

$ ruby -I.:lib:test test/mass_assignment_security/sanitizer_test.rb zer_test.rb 
test/mass_assignment_security/sanitizer_test.rb:4:in `<main>': uninitialized constant ActiveModel (NameError)

They passes if -ractive_model/mass_assignment_security is specified on the command line. Could you please add this require somewhere into the code to remove the need of additional parameter? Thanks.

ArgumentError in tests with Rails 4.1.10rc2

Running the tests on Ruby 2.1.5 with

gem 'rails', '4.1.10.rc2'

in the Gemfile yields the following error (attn: @rafaelfranca ):

  1. Error:
    MassAssignmentSecurityHasManyRelationsTest#test_has_many_through_build_with_attr_accessible_attributes:
    ArgumentError: wrong number of arguments (2 for 1)
    /home/rst/gemhome215/gems/activerecord-4.1.10.rc2/lib/active_record/associations/through_association.rb:96:in build_record' /home/rst/src/protected_attributes/lib/active_record/mass_assignment_security/associations.rb:72:inbuild_record'
    /home/rst/src/protected_attributes/lib/active_record/mass_assignment_security/associations.rb:19:in build' /home/rst/src/protected_attributes/lib/active_record/mass_assignment_security/associations.rb:55:inbuild'
    /home/rst/src/protected_attributes/test/attribute_sanitization_test.rb:687:in `test_has_many_through_build_with_attr_accessible_attributes'

protected_attributes is not capatible with rails 5.2.3 with ruby 2..6.3

Bundler could not find compatible versions for gem "activemodel":
In snapshot (Gemfile.lock):
activemodel (= 5.2.3)

In Gemfile:
draper was resolved to 3.1.0, which depends on
activemodel-serializers-xml (>= 1.0) was resolved to 1.0.2, which depends on
activemodel (> 5.x)

protected_attributes was resolved to 1.0.2, which depends on
  activemodel (>= 4.0.0.beta, < 5.0)

rails (~> 5.2.3) was resolved to 5.2.3, which depends on
  activemodel (= 5.2.3)

web-console (>= 3.3.0) was resolved to 3.7.0, which depends on
  activemodel (>= 5.0)

is there any other way to make compatible it with rails 5.2.3 to access attrtibutes

3rd-party lib depending on ActiveModel broken

ActiveModel::MassAssignmentSecurity was extracted from ActiveModel into this gem. This breaks things like Mongoid which depends on ActiveModel::MassAssignmentSecurity but not ActiveRecord.

Allow :without_protection on parent.child.build(:type => 'MyStiClass')

Currently if a model is using attr_protected (instead of attr_accessible) - its impossible to use the Rails 4.0 inheritance syntax for generating Single Table Inheritance classes.

parent_class.child_association.build({ :type => 'MyStiType' }, :without_protection => true)

The without_protection => true option is honoured by attr_accessible, but the subclass_for_attributes? in inheritance.rb ignores this option, so still does checks against the attr_protected attributes + the defaults of 'id' and 'type'.

This means the type attribute cannot get assigned, removing the ability to create STI models.

find_or_ methods not being overridden

In Rails 3.2, find_or_initialize_by(foo: :bar) and find_or_create_by(foo: :bar) bypassed mass-assignment protection. With Rails 4.1 and protected_attributes, those still raise mass assignment errors, but where(foo: :bar).first_or_initialize and where(foo: :bar).first_or_create work as expected.

Is this intentional, or was it just accidentally not supported?

regression: attr_accessible is added to all models

Isn't this a regression?

https://github.com/rails/protected_attributes/blob/master/lib/protected_attributes/railtie.rb#L10-L15

In rails 3 attr_accessible was not added to all models, but with this gem, in rails 4, it is... Sure, this might be a "Best practice" but I thought this gem was supposed to be a kludge to keep the same behavior that was supported in rails 3 around in rails 4 - which helps support the upgrade path.

Now, with this gem, that behavior has changed. So updating a legacy rails 3 app to rails 4 forces breaking changes.

Should this new behavior be configurable?

Test suite fails when executed in "random" order

It is passing when files are sorted:

$ ruby -Ilib:test -e 'Dir.glob("./test/**/*_test.rb").sort.each &method(:require)'
Run options: --seed 30864

# Running:

......................................................................................................................................................................

Finished in 0.571150s, 290.6415 runs/s, 1066.2690 assertions/s.

166 runs, 609 assertions, 0 failures, 0 errors, 0 skips

But failing when they are unsorted:

$ ruby -Ilib:test -e 'Dir.glob("./test/**/*_test.rb").each &method(:require)'
/builddir/build/BUILD/protected_attributes-1.0.8/usr/share/gems/gems/protected_attributes-1.0.8/test/models/pirate.rb:1:in `<top (required)>': uninitialized constant ActiveRecord (NameError)
    from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /builddir/build/BUILD/protected_attributes-1.0.8/usr/share/gems/gems/protected_attributes-1.0.8/test/mass_assignment_security_test.rb:4:in `<top (required)>'
    from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
    from -e:1:in `each'
    from -e:1:in `<main>'

super: no superclass method `subclass_from_attributes?' for #<Class:0x007fe284c484c0>

def new
  @_design = @_crowdshop.fans.new
end
vendor/ruby/2.0.0/gems/activerecord-4.0.3/lib/active_record/dynamic_matchers.rb:22:in `method_missing'
vendor/ruby/2.0.0/gems/protected_attributes-1.0.6/lib/active_record/mass_assignment_security/inheritance.rb:13:in `subclass_from_attributes?'
vendor/ruby/2.0.0/gems/activerecord-4.0.3/lib/active_record/inheritance.rb:22:in `new'
vendor/ruby/2.0.0/gems/protected_attributes-1.0.6/lib/active_record/mass_assignment_security/reflection.rb:6:in `build_association'
vendor/ruby/2.0.0/gems/protected_attributes-1.0.6/lib/active_record/mass_assignment_security/associations.rb:5:in `build_record'
vendor/ruby/2.0.0/gems/protected_attributes-1.0.6/lib/active_record/mass_assignment_security/associations.rb:19:in `build'
vendor/ruby/2.0.0/gems/protected_attributes-1.0.6/lib/active_record/mass_assignment_security/associations.rb:55:in `build'

Bug using prepend module, save does not populate the fiels

Hi.

I just find a bug in the gem that force me to remove strong_parameter in my app.

Here is the code that work (rails only)

unless File.exist?('Gemfile')
  File.write('Gemfile', <<-GEMFILE)
    source 'https://rubygems.org'
    gem 'rails', '~> 4.2' #, github: 'rails/rails'
    gem 'arel'            #, github: 'rails/arel'
    gem 'sqlite3'
  GEMFILE

  system 'bundle'
end

require 'bundler'
Bundler.setup(:default)

require 'active_record'
require 'minitest/autorun'
require 'logger'

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true  do |t|
    t.string :title
  end

  create_table :post_infos, force: true  do |t|
    t.integer :post_id
    t.string  :basic_field
    t.string  :prepended_field
  end
end

module Prepends
  module Post

    def post_info
      merged_attributes = { prepended_field: 'YATA' }.stringify_keys.merge(super().try(:attributes) || {})

      if super.nil?
        send(:build_post_info, merged_attributes )
      elsif (!super().valid? && self.new_record?)
        super().attributes   = merged_attributes
        super()
      else
        super()
      end
    end
  end
end

class Post < ActiveRecord::Base
  prepend Prepends::Post

  has_one :post_info, dependent: :destroy
  accepts_nested_attributes_for :post_info, allow_destroy: true
end

class PostInfo < ActiveRecord::Base
  belongs_to :post
  validates :prepended_field, presence: true
end

class BugTest < Minitest::Test
  def test_association_stuff
    post = Post.new( { title: 'Testing', post_info_attributes: { basic_field: 'YOLO' } } )

    post.save!
    assert_equal 1,                 PostInfo.count
    assert_equal post.id,           PostInfo.first.post.id
    assert_equal 'YOLO',            PostInfo.first.basic_field
    assert_equal 'YATA',            PostInfo.first.prepended_field
  end
end

Here is the code that failed (with protected_attributes)

unless File.exist?('Gemfile')
  File.write('Gemfile', <<-GEMFILE)
    source 'https://rubygems.org'
    gem 'rails', '~> 4.2' #, github: 'rails/rails'
    gem 'arel'            #, github: 'rails/arel'
    gem 'sqlite3'
    gem 'protected_attributes'
  GEMFILE

  system 'bundle'
end

require 'bundler'
Bundler.setup(:default)

require 'active_record'
require 'minitest/autorun'
require 'logger'
require 'protected_attributes'

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true  do |t|
    t.string :title
  end

  create_table :post_infos, force: true  do |t|
    t.integer :post_id
    t.string  :basic_field
    t.string  :prepended_field
  end
end

module Prepends
  module Post

    def post_info
      merged_attributes = { prepended_field: 'YATA' }.stringify_keys.merge(super().try(:attributes) || {})

      if super.nil?
        send(:build_post_info, merged_attributes )
      elsif (!super().valid? && self.new_record?)
        super().attributes   = merged_attributes
        super()
      else
        super()
      end
    end
  end
end

class Post < ActiveRecord::Base
  prepend Prepends::Post

  has_one :post_info, dependent: :destroy
  accepts_nested_attributes_for :post_info, allow_destroy: true

  attr_accessible :title, :post_info_attributes
end

class PostInfo < ActiveRecord::Base
  belongs_to :post
  validates :prepended_field, presence: true

  attr_accessible :basic_field, :prepended_field
end

class BugTest < Minitest::Test
  def test_association_stuff
    post = Post.new( { title: 'Testing', post_info_attributes: { basic_field: 'YOLO' } } )

    post.save!
    assert_equal 1,                 PostInfo.count
    assert_equal post.id,           PostInfo.first.post.id
    assert_equal 'YOLO',            PostInfo.first.basic_field
    assert_equal 'YATA',            PostInfo.first.prepended_field
  end
end

Which produce :

Finished in 0.028528s, 35.0529 runs/s, 0.0000 assertions/s.

  1) Error:
BugTest#test_association_stuff:
ActiveRecord::RecordInvalid: Validation failed: Post info prepended field can't be blank
    ~/codes/tmp/.gems/gems/activerecord-4.2.1/lib/active_record/validations.rb:79:in `raise_record_invalid'
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
``

Gradual upgrade path to strong_parameters

During my upgrade to Rails 4, I decided to postpone the removal of attr_accessible and use this gem. Now, I would like to drop this in favor of strong_parameters. Since our application is fairly large, I would like to do this gradually.

I've been trying to follow the instructions here: https://github.com/rails/strong_parameters#migration-path-to-rails-4. However, when I set config.active_record.whitelist_attributes = false and include ActiveModel::ForbiddenAttributesProtection in one of my models, the following statement still proceeds to instantiate a user without any problems:

User.new(ActionController::Parameters.new(first_name: 'Ruben'))

According to my understanding of strong_parameters, this should throw a ActiveModel::ForbiddenAttributesError. Basically, strong_parameters does not seem to be working, or the protected_attributes is conflicting somehow.

Can anyone help me with this problem?

Problem with protected_attributes and nested_attributes on Rails 4.1.2

After upgrading one of our applications to Rails 4.1.2 the test suite failed with some associations showing more links than expected. I've tracked this down to an interaction between the protected_attributes gem and #accepts_nested_attributes_for in Rails 4.1.2. Previous versions of Rails 4.1.x, 4.0.x and 3.2.x do not exhibit this problem. I've reproduced the error with both protected_attributes 1.0.8 and 1.0.7.

I've created a very simple Rails 4.1.2 app which demonstrates the problem but the summary of if is:

BusinessUnit.create(reference: '123')
bu = BusinessUnit.find_by(reference: '123')
ws = Worksite.where(reference: '456').first_or_initialize # Does not exist so initialize is called
ws.business_units = [bu]
pa = ws.build_postal_address(reference: '1234')
ws.save

At this point you'd expect ws.business_units.count to be 1 but it is, in fact 2. This is repeatable on both create and update.

Removing either the protected_attributes gem or #accepts_nested_attributes_for fixes the problem.

The trivial models in my test application to reproduce this error are:

class BusinessUnit < ActiveRecord::Base
  has_many :worksites, :through => :worksites_business_units
  has_many :worksites_business_units, :dependent => :delete_all
  attr_accessible :reference if self.respond_to?(:attr_accessible)
end

class PostalAddress < ActiveRecord::Base
  has_one :worksite
  attr_accessible :reference if self.respond_to?(:attr_accessible)
end

class Worksite < ActiveRecord::Base
  belongs_to :postal_address
  has_many :business_units, :through => :worksites_business_units
  has_many :worksites_business_units, :dependent => :delete_all
  accepts_nested_attributes_for :postal_address
end

class WorksitesBusinessUnit < ActiveRecord::Base
  belongs_to :worksite
  belongs_to :business_unit
end

And the test looks like:

require 'test_helper'

class WorksiteTest < ActiveSupport::TestCase
    test "protected attributes and nested attributes play together" do
    bu = BusinessUnit.find_by(reference: '123')
    ws = Worksite.where(reference: '456').first_or_initialize
    ws.business_units = [bu]
    pa = ws.build_postal_address(reference: '789')
    ws.save
    assert_equal 1, ws.business_units.count
  end
end

The log extract from the test clearly shows two records being saved in the joining table:

   (0.3ms)  SAVEPOINT active_record_1
  SQL (0.4ms)  INSERT INTO `postal_addresses` (`created_at`, `reference`, `updated_at`) VALUES ('2014-07-01 10:28:49', '789', '2014-07-01 10:28:49')
  PostalAddress Load (0.4ms)  SELECT  `postal_addresses`.* FROM `postal_addresses`  WHERE `postal_addresses`.`id` = 980190973 LIMIT 1
  SQL (0.3ms)  INSERT INTO `worksites` (`created_at`, `postal_address_id`, `reference`, `updated_at`) VALUES ('2014-07-01 10:28:49', 980190973, '456', '2014-07-01 10:28:49')
  SQL (0.2ms)  INSERT INTO `worksites_business_units` (`business_unit_id`, `created_at`, `updated_at`) VALUES (980190962, '2014-07-01 10:28:49', '2014-07-01 10:28:49')
  SQL (0.4ms)  UPDATE `worksites_business_units` SET `updated_at` = '2014-07-01 10:28:49', `worksite_id` = 980190973 WHERE `worksites_business_units`.`id` = 980190979
  SQL (0.2ms)  INSERT INTO `worksites_business_units` (`business_unit_id`, `created_at`, `updated_at`, `worksite_id`) VALUES (980190962, '2014-07-01 10:28:49', '2014-07-01 10:28:49', 980190973)

We have several models / relationships that use this pattern and we're seeing the same behaviour in all of them.

wrong number of arguments in build_record

Hello,
This may have been handled by #50. But even with my app pointed at master for protected_attributes and rails 4-2-stable. When I call build on a has_many_through relation, I get

ArgumentError (wrong number of arguments (2 for 1)): /Users/danielamiller/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/rails-eb53536a1ccd/activerecord/lib/active_record/associations/through_association.rb:95:in build_record' /Users/danielamiller/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/protected_attributes-61e622368d66/lib/active_record/mass_assignment_security/associations.rb:72:in build_record' /Users/danielamiller/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/protected_attributes-61e622368d66/lib/active_record/mass_assignment_security/associations.rb:19:in build' /Users/danielamiller/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/protected_attributes-61e622368d66/lib/active_record/mass_assignment_security/associations.rb:55:inbuild'`

A small caveat I am using the class_name option so it looks like
has_many : foos, class_name: "Bar".

Any help is greatly appreciated.

unhandled dependency on railties

protected_attributes depends on railties if Rails is defined:
6886ec7

This presumably is meant to test whether all of the rails gem is installed, which would guarantee railties was too. Unfortunately, there exist gmes that define Rails, but don't require railtie. I happen to be using one.

It seems we should specifically test whether Rails::Railtie is defined.

Protected Attributes breaks Heroku deployment of Rails 4 apps

Using Rails 4.0.0.beta1 with protected_attributes makes heroku deployments fail on precompilation, even using config.assets.initialize_on_precompile = false and heroku labs user-env-compile. Here's a sample of the stack trace:

       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_record/mass_assignment_security/attribute_assignment.rb:15:in `attributes_protected_by_default'
       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_model/mass_assignment_security.rb:332:in `block in protected_attributes_configs'
       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_model/mass_assignment_security.rb:217:in `yield'
       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_model/mass_assignment_security.rb:217:in `protected_attributes'
       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_model/mass_assignment_security.rb:123:in `block in attr_protected'
       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_model/mass_assignment_security.rb:122:in `each'
       /tmp/build_2ts1np9ko79to/vendor/bundle/ruby/2.0.0/gems/protected_attributes-1.0.0/lib/active_model/mass_assignment_security.rb:122:in `attr_protected'

I have no idea why this is the case, but removing protected_attributes from my gemfile immediately fixed the problem.

I'll do some more research and post notes if I figure out what the gem was doing that caused this problem, but in the mean time I wanted to post this issue in case others are running into the same problem.

Error when creating record in 1.0.5

I have a model that is instantiated using first_or_create:

def session_api_key
api_keys.active.session.first_or_create()
end

Upgrading from 1.0.3 to 1.0.5 produces the error below:

ArgumentError: wrong number of arguments (2 for 0..1)
from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/core.rb:180:in initialize' from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/inheritance.rb:27:innew'
from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/inheritance.rb:27:in new' from /Users/martin/.gem/ruby/2.0.0/gems/protected_attributes-1.0.5/lib/active_record/mass_assignment_security/persistence.rb:45:increate'
from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/relation.rb:121:in block in create' from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/relation.rb:270:inscoping'
from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/relation.rb:121:in create' from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/relation.rb:133:infirst_or_create'
from /Users/martin/code/brightseeds/app/models/user.rb:39:in session_api_key' from (irb):17 from /Users/martin/.gem/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands/console.rb:90:instart'
from /Users/martin/.gem/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in start' from /Users/martin/.gem/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands.rb:64:in<top (required)>'
from ./script/rails:6:in require' from ./script/rails:6:in

'

This can also be triggered by a simple create in the console:

irb(main):008:0> ApiKey.create
ArgumentError: wrong number of arguments (2 for 0..1)
from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/core.rb:180:in initialize' from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/inheritance.rb:27:innew'
from /Users/martin/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/inheritance.rb:27:in new' from /Users/martin/.gem/ruby/2.0.0/gems/protected_attributes-1.0.5/lib/active_record/mass_assignment_security/persistence.rb:45:increate'
from (irb):8
from /Users/martin/.gem/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in start' from /Users/martin/.gem/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands/console.rb:9:instart'
from /Users/martin/.gem/ruby/2.0.0/gems/railties-4.0.0/lib/rails/commands.rb:64:in <top (required)>' from ./script/rails:6:inrequire'
from ./script/rails:6:in `

'

NoMethodError: undefined method `sanitize' for false:FalseClass

/Users/guyren/.rvm/gems/ruby-2.1.0/gems/protected_attributes-1.0.8/lib/active_model/mass_assignment_security.rb:346:in `sanitize_for_mass_assignment’

which is where the gem asks itself for a sanitizer object and fails.

I’ve got:

config.active_record.whitelist_attributes = true

I believe the problem maybe arises in some fashion from the object I’m trying to save having a json field.

Rails 4.1.

Rails 4.2 HasManyThroughAssociation build_record arity mismatch

Hey there, thanks for the gem.

I know that the current release only claims to support rails 4.1, but I figured I'd mention an issue I'm having on rails 4.2 (amidst an upgrade from 3.2 :)

In rails 4.1 Associations::HasManyThroughAssociation defines build_record(attributes, options={}) whereas rails 4.2 defines build_record(attributes), so protected_attributes' super call causes an ArgumentError.

I'd be happy to take a stab at fixing, but wanted to know your plans on supporting rails 4.2 before diving in. Monkey patching for now.

UPDATE

On second thought, if this gem is to be supported until rails 5.0, perhaps the fix needs to be in rails 4.2? Their arity change breaks this gem.

[Rails 5] unable to insert on db migrate

Work on Rails 4, but not work on Rails 5.

https://bitbucket.org/marutosi/rails5-sandbox/src/1225062885/db/migrate/001_setup.rb#cl-18

class Setup < ActiveRecord::Migration
  # model removed
  class Permission < ActiveRecord::Base
    attr_protected :id
  end

  def self.up
    create_table "permissions", :force => true do |t|
      t.column "controller", :string, :limit => 30, :default => "", :null => false
    end

    Permission.create :controller => "projects"
  end

  def self.down
  end
end
$ rake db:migrate RAILS_ENV=test
== 1 Setup: migrating =========================================================
-- create_table("permissions", {:force=>true})
   -> 0.0044s
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

wrong number of arguments (2 for 0..1)/home/xxx/.rvm/gems/ruby-2.2.2/bundler/gems/rails-fcc46833a88c/activerecord/lib/active_record/core.rb:295:in `initialize'
/home/xxx/.rvm/gems/ruby-2.2.2/bundler/gems/rails-fcc46833a88c/activerecord/lib/active_record/inheritance.rb:61:in `new'
/home/xxx/.rvm/gems/ruby-2.2.2/bundler/gems/rails-fcc46833a88c/activerecord/lib/active_record/inheritance.rb:61:in `new'
/home/xxx/.rvm/gems/ruby-2.2.2/bundler/gems/protected_attributes-95c8eb506276/lib/active_record/mass_assignment_security/persistence.rb:45:in `create'
/REDMINE/hg-workdir/homuhomu/db/migrate/001_setup.rb:29:in `up'

Protected attributes breaks creation by array

It seems protected_attributes is preventing creating multiple records using an array. ie

class Foo < ActiveRecord::Base
  attr_accesssible :bar
end

Foo.new({bar: 'baz'})   # => works
Foo.new([{bar: 'baz'},{bar: 'boo'}])   # => throws an error

The error I get is

undefined method `stringify_keys' for #<Array:0x007faa7d6c76c0>
in gems/protected_attributes-1.0.8/lib/active_record/mass_assignment_security/attribute_assignment.rb:51:in `assign_attributes'

As far as I can tell this method of initializing multiple objects is officially supported in the Rails docs

Don't understand how this gem can work with rails 4 (cross-post)

Hi,

I'm having following problems: attr-encrypted/attr_encrypted#246

And i really don't understand how the "protected_attributes" gem can work, because it uses following method (with 2! parameters):

assign_attributes(attributes, options)

But in ActiveRecord 4 there is no method like this - because the only assign_attributes method has following signature (1! parameter):

# activerecord-4.2.7.1/lib/active_record/attribute_assignment.rb
   ...
    def assign_attributes(new_attributes)

Can someone give me a hint how this can work? And why I get this error, even if the gems themselfes should work fine with rails 4.2? Thanks :(

This gem seems to completely disable strong_parameters in rails 4 apps?

We transitioned our rails 3 app which used strong_parameters and had some models relying on attr_accessible and some on strong_parameters to rails 4. We included this gem and discovered that it opened all models that were previously protected by strong_parameters to the world. This isn't stated in the readme or anywhere obvious I don't think and seems like a HUGE security issue for apps that are transitioning. Am I missing something here?

StackTrace when use protected_attributes in gem

I want to use protected_attributes gem in gem with models(and migrations). It works correctly in this gem - all migrations and specs pass, but when i try to rebuild database in main application, which uses gem with models, i got such error(I try to do it in a few different applications and gems with the same result).

StandardError: An error has occurred, this and all later migrations canceled:

PG::NotNullViolation: ERROR:  null value in column "version" violates not-null constraint
DETAIL:  Failing row contains (null).
: INSERT INTO "models"."schema_migrations" DEFAULT VALUES/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `async_exec'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `block in exec_no_cache'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract_adapter.rb:373:in `block in log'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract_adapter.rb:367:in `log'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `exec_no_cache'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql/database_statements.rb:137:in `exec_query'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql/database_statements.rb:177:in `exec_insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:95:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/relation.rb:64:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:503:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/attribute_methods/dirty.rb:87:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:306:in `block in _create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/callbacks.rb:82:in `run_callbacks'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:306:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/timestamp.rb:57:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:483:in `create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:302:in `block in create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/callbacks.rb:82:in `run_callbacks'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:302:in `create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:125:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/validations.rb:57:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/attribute_methods/dirty.rb:29:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:273:in `block in save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:329:in `block in with_transaction_returning_status'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:199:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:208:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:326:in `with_transaction_returning_status'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:273:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/protected_attributes-1.0.9/lib/active_record/mass_assignment_security/validations.rb:17:in `create!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/schema_migrator-0.2.0/lib/schema_migrator/rake_task.rb:183:in `record_version_state_after_migrating'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:999:in `block in execute_migration_in_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:1044:in `block in ddl_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `block in transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:209:in `within_new_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:208:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:1044:in `ddl_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/pg_saurus-2.2.1/lib/pg_saurus/create_index_concurrently.rb:207:in `ddl_transaction_with_postponed_queries'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:997:in `execute_migration_in_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:959:in `block in migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:955:in `each'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:955:in `migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:814:in `up'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:792:in `migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/schema_migrator-0.2.0/lib/schema_migrator/rake_task.rb:29:in `block (2 levels) in define_rake_tasks!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/bin/ruby_executable_hooks:15:in `eval'
/home/user/.rvm/gems/ruby-2.1.2@my_application/bin/ruby_executable_hooks:15:in `<main>'
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR:  null value in column "version" violates not-null constraint
DETAIL:  Failing row contains (null).
: INSERT INTO "models"."schema_migrations" DEFAULT VALUES
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `async_exec'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `block in exec_no_cache'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract_adapter.rb:373:in `block in log'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract_adapter.rb:367:in `log'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `exec_no_cache'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql/database_statements.rb:137:in `exec_query'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql/database_statements.rb:177:in `exec_insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:95:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/relation.rb:64:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:503:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/attribute_methods/dirty.rb:87:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:306:in `block in _create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/callbacks.rb:82:in `run_callbacks'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:306:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/timestamp.rb:57:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:483:in `create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:302:in `block in create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/callbacks.rb:82:in `run_callbacks'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:302:in `create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:125:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/validations.rb:57:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/attribute_methods/dirty.rb:29:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:273:in `block in save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:329:in `block in with_transaction_returning_status'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:199:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:208:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:326:in `with_transaction_returning_status'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:273:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/protected_attributes-1.0.9/lib/active_record/mass_assignment_security/validations.rb:17:in `create!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/schema_migrator-0.2.0/lib/schema_migrator/rake_task.rb:183:in `record_version_state_after_migrating'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:999:in `block in execute_migration_in_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:1044:in `block in ddl_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `block in transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:209:in `within_new_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:208:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:1044:in `ddl_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/pg_saurus-2.2.1/lib/pg_saurus/create_index_concurrently.rb:207:in `ddl_transaction_with_postponed_queries'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:997:in `execute_migration_in_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:959:in `block in migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:955:in `each'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:955:in `migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:814:in `up'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:792:in `migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/schema_migrator-0.2.0/lib/schema_migrator/rake_task.rb:29:in `block (2 levels) in define_rake_tasks!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/bin/ruby_executable_hooks:15:in `eval'
/home/user/.rvm/gems/ruby-2.1.2@my_application/bin/ruby_executable_hooks:15:in `<main>'
PG::NotNullViolation: ERROR:  null value in column "version" violates not-null constraint
DETAIL:  Failing row contains (null).
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `async_exec'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `block in exec_no_cache'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract_adapter.rb:373:in `block in log'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract_adapter.rb:367:in `log'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql_adapter.rb:822:in `exec_no_cache'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql/database_statements.rb:137:in `exec_query'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/postgresql/database_statements.rb:177:in `exec_insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:95:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/relation.rb:64:in `insert'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:503:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/attribute_methods/dirty.rb:87:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:306:in `block in _create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/callbacks.rb:82:in `run_callbacks'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:306:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/timestamp.rb:57:in `_create_record'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:483:in `create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:302:in `block in create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activesupport-4.1.9/lib/active_support/callbacks.rb:82:in `run_callbacks'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/callbacks.rb:302:in `create_or_update'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/persistence.rb:125:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/validations.rb:57:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/attribute_methods/dirty.rb:29:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:273:in `block in save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:329:in `block in with_transaction_returning_status'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:199:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:208:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:326:in `with_transaction_returning_status'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:273:in `save!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/protected_attributes-1.0.9/lib/active_record/mass_assignment_security/validations.rb:17:in `create!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/schema_migrator-0.2.0/lib/schema_migrator/rake_task.rb:183:in `record_version_state_after_migrating'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:999:in `block in execute_migration_in_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:1044:in `block in ddl_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `block in transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:209:in `within_new_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/transactions.rb:208:in `transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:1044:in `ddl_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/pg_saurus-2.2.1/lib/pg_saurus/create_index_concurrently.rb:207:in `ddl_transaction_with_postponed_queries'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:997:in `execute_migration_in_transaction'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:959:in `block in migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:955:in `each'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:955:in `migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:814:in `up'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/activerecord-4.1.9/lib/active_record/migration.rb:792:in `migrate'
/home/user/.rvm/gems/ruby-2.1.2@my_application/gems/schema_migrator-0.2.0/lib/schema_migrator/rake_task.rb:29:in `block (2 levels) in define_rake_tasks!'
/home/user/.rvm/gems/ruby-2.1.2@my_application/bin/ruby_executable_hooks:15:in `eval'
/home/user/.rvm/gems/ruby-2.1.2@my_application/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => db:rebuild => db:migrate => app:db:migrate => app:models_core:db:migrate
(See full trace by running task with --trace).

Stack Trace is not useful when there's an error in process_removed_attributes

I want to know which line in the app causes the error.

  An error occurred in an after hook
    ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes for CustomShipMethod: in_store_pickup
    occurred at /home/phoenix/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/protected_attributes-1.0.8/lib/active_model/mass_assignment_security/sanitizer.rb:60:in `process_removed_attributes'

protected_attributes + nested attributes invokes callbacks twice

I upgraded from Rails 4.0 to Rails 4.1 and noticed that some callbacks are being invoked twice. I've narrowed it down to the interaction between protected_attributes gem and nested attributes.

I've distilled the problem in a simple app (affects both Rails 4.1 and Rails 4.2),

but it works with Rails 4.0: https://github.com/pkmiec/buggy/tree/rails40

The app basically has,

class Portfolio < ActiveRecord::Base
  belongs_to :contact_info
  accepts_nested_attributes_for :contact_info

  after_update do |obj|
    puts "AFTER_UPDATE"
  end
end

class ContactInfo < ActiveRecord::Base
  has_one :portfolio
end

class PortfolioTest < ActiveSupport::TestCase
  test "the truth" do
    ci = ContactInfo.create!
    portfolio = Portfolio.create!(:contact_info_id => ci.id)

    attrs = {
      :contact_info_attributes => {
      }
    }

    puts "--- begin"
    portfolio.attributes = attrs
    puts "--- middle"
    portfolio.save!
    puts "--- end"
  end
end

Running the test,

%> rake
--- begin
--- middle
AFTER_UPDATE
AFTER_UPDATE
--- end

If you comment out gem 'protected_attributed' from the Gemfile you get the correct behavior,

%> rake
--- begin
--- middle
AFTER_UPDATE
--- end

Rails 4.1 Compatibility

When using Rails 4.1 this error is thrown:

/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-4.1.0.beta1/lib/active_record/dynamic_matchers.rb:22:in method_missing': undefined local variable or methodgenerated_feature_methods' for #Class:0x007fb98e4e5120 (NameError)
from /.rvm/gems/ruby-2.0.0-p247/gems/protected_attributes-1.0.5/lib/active_record/mass_assignment_security/nested_attributes.rb:30:in block in accepts_nested_attributes_for' from /.rvm/gems/ruby-2.0.0-p247/gems/protected_attributes-1.0.5/lib/active_record/mass_assignment_security/nested_attributes.rb:16:ineach'
from /.rvm/gems/ruby-2.0.0-p247/gems/protected_attributes-1.0.5/lib/active_record/mass_assignment_security/nested_attributes.rb:16:in `accepts_nested_attributes_for'

Tag 1.0.9

Minor issue.

Tag 1.0.9 is not present in the tags list.

Thanks

undefined method `[]' for nil:NilClass

I recently upgraded from Rails 4.0.0 to Rails 4.0.2 and simultaneously upgraded from protected_attributes 1.0.3 to 1.0.5.

When I try to access a column (string) in a model which has been retrieved from memcache via Rails.cache.fetch I get the following error in our production environment:

NoMethodError: undefined method `[]' for nil:NilClass

Oddly enough, this doesn't occur in our development environment or in the console in our production environment.

Below is the relevant portion of the stacktrace.

/gems/activerecord-4.0.2/lib/active_record/attribute_methods/read.rb:86 in "block in read_attribute"
/gems/activerecord-4.0.2/lib/active_record/attribute_methods/read.rb:84 in "fetch"
/gems/activerecord-4.0.2/lib/active_record/attribute_methods/read.rb:84 in "read_attribute"
/gems/activerecord-4.0.2/lib/active_record/attribute_methods/read.rb:59 in "__temp__4786f657768647"

Release version 1.0.6

Most the commits after 1.0.5 release are related to make protected_attributes work with rails 4.1. So we need a new release so we can use this + rails 4.1.

thanks

Test failure with mocha 1.7.0 - Mocha::NotInitializedError: Mocha methods cannot be used outside the context of a test

Originally reported here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=912253 (it has full log)

pravi@andhaka:~/forge/debian/git/ruby-team/ruby-protected-attributes$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/...........
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Fetching rake 12.3.1
Installing rake 12.3.1
Fetching concurrent-ruby 1.1.1
Installing concurrent-ruby 1.1.1
Fetching i18n 0.9.5
Installing i18n 0.9.5
Fetching minitest 5.11.3
Installing minitest 5.11.3
Fetching thread_safe 0.3.6
Installing thread_safe 0.3.6
Fetching tzinfo 1.2.5
Installing tzinfo 1.2.5
Fetching activesupport 4.2.10
Installing activesupport 4.2.10
Fetching builder 3.2.3
Installing builder 3.2.3
Fetching erubis 2.7.0
Installing erubis 2.7.0
Fetching mini_portile2 2.3.0
Installing mini_portile2 2.3.0
Fetching nokogiri 1.8.5
Installing nokogiri 1.8.5 with native extensions
Fetching rails-deprecated_sanitizer 1.0.3
Installing rails-deprecated_sanitizer 1.0.3
Fetching rails-dom-testing 1.0.9
Installing rails-dom-testing 1.0.9
Fetching crass 1.0.4
Installing crass 1.0.4
Fetching loofah 2.2.3
Installing loofah 2.2.3
Fetching rails-html-sanitizer 1.0.4
Installing rails-html-sanitizer 1.0.4
Fetching actionview 4.2.10
Installing actionview 4.2.10
Fetching rack 1.6.11
Installing rack 1.6.11
Fetching rack-test 0.6.3
Installing rack-test 0.6.3
Fetching actionpack 4.2.10
Installing actionpack 4.2.10
Fetching globalid 0.4.1
Installing globalid 0.4.1
Fetching activejob 4.2.10
Installing activejob 4.2.10
Fetching mini_mime 1.0.1
Installing mini_mime 1.0.1
Fetching mail 2.7.1
Installing mail 2.7.1
Fetching actionmailer 4.2.10
Installing actionmailer 4.2.10
Fetching activemodel 4.2.10
Installing activemodel 4.2.10
Fetching arel 6.0.4
Installing arel 6.0.4
Fetching activerecord 4.2.10
Installing activerecord 4.2.10
Using bundler 1.16.1
Fetching metaclass 0.0.4
Installing metaclass 0.0.4
Fetching mocha 1.7.0
Installing mocha 1.7.0
Using protected_attributes 1.1.4 from source at `.`
Fetching thor 0.20.0
Installing thor 0.20.0
Fetching railties 4.2.10
Installing railties 4.2.10
Fetching sprockets 3.7.2
Installing sprockets 3.7.2
Fetching sprockets-rails 3.2.1
Installing sprockets-rails 3.2.1
Fetching rails 4.2.10
Installing rails 4.2.10
Fetching sqlite3 1.3.13
Installing sqlite3 1.3.13 with native extensions
Bundle complete! 7 Gemfile dependencies, 38 gems now installed.
Bundled gems are installed into `./vendor/bundle`
pravi@andhaka:~/forge/debian/git/ruby-team/ruby-protected-attributes$ bundle exec rake
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/core_ext/hash/slice.rb:21: warning: method redefined; discarding old slice
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/core_ext/hash/keys.rb:8: warning: method redefined; discarding old transform_keys
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/core_ext/hash/keys.rb:19: warning: method redefined; discarding old transform_keys!
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/core_ext/object/duplicable.rb:111: warning: BigDecimal.new is deprecated; use Kernel.BigDecimal method instead.
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.10/lib/active_support/core_ext/enumerable.rb:20: warning: method redefined; discarding old sum
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/arel-6.0.4/lib/arel/visitors/informix.rb:20: warning: assigned but unused variable - froms
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/lib/active_record/mass_assignment_security/associations.rb:82: warning: method redefined; discarding old build_record
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activerecord-4.2.10/lib/active_record/associations/through_association.rb:89: warning: previous definition of build_record was here
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/lib/active_record/mass_assignment_security/associations.rb:116: warning: method redefined; discarding old options_for_through_record
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/activerecord-4.2.10/lib/active_record/associations/has_many_through_association.rb:106: warning: previous definition of options_for_through_record was here
Run options: --seed 29684

# Running:

.........................................................................................EEE.................................................................................................................

   1) derived wrapped keys from specified model
      Mocha::NotInitializedError: Mocha methods cannot be used outside the context of a test
          /home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/test/accessible_params_wrapper_test.rb:54:in `block in test_derived_wrapped_keys_from_specified_model'
          /home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/test/accessible_params_wrapper_test.rb:9:in `with_default_wrapper_options'
      # test/accessible_params_wrapper_test.rb:54
      # test/accessible_params_wrapper_test.rb:9
      # test/accessible_params_wrapper_test.rb:53

   2) derived wrapped keys from matching model
      Mocha::NotInitializedError: Mocha methods cannot be used outside the context of a test
      # test/accessible_params_wrapper_test.rb:41

   3) accessible wrapped keys from matching model
      Mocha::NotInitializedError: Mocha methods cannot be used outside the context of a test
      # test/accessible_params_wrapper_test.rb:67

Finished in 0.761185s, 269.3169 runs/s, 960.3448 assertions/s.
205 runs, 731 assertions, no failures, 3 errors, no skips

Failed Tests:

rake TEST=/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/test/accessible_params_wrapper_test.rb TESTOPTS="--name=test_derived_wrapped_keys_from_specified_model"
rake TEST=/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/test/accessible_params_wrapper_test.rb TESTOPTS="--name=test_derived_wrapped_keys_from_matching_model"
rake TEST=/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/test/accessible_params_wrapper_test.rb TESTOPTS="--name=test_accessible_wrapped_keys_from_matching_model"

rake aborted!
Command failed with status (1)
/home/pravi/forge/debian/git/ruby-team/ruby-protected-attributes/vendor/bundle/ruby/2.5.0/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'
Tasks: TOP => default => test
(See full trace by running task with --trace)

ActiveSupport 4.2.0 breaks backtrace_cleaner

Mass assignment causes protected_attributes to error on mass-assignment, complaining that Rails.backtrace_cleaner is not a thing.

It appears it has been moved out of the Rails module.

incompatible with Rails 5

.build function is broken in rails5 due to something in protect_attributes. Hopefully not hard to fix. Below is some sample code to cause the error and the full trace.

> @item = ItemType.new
=> #<ItemType id: nil, name: nil, .... >
> @item.item_abilities
=> #<ActiveRecord::Associations::CollectionProxy []>
> @item.item_abilities.build
ArgumentError: wrong number of arguments (given 2, expected 0..1)
from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.rc2/lib/active_record/core.rb:312:in `initialize'
from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.rc2/lib/active_record/inheritance.rb:65:in `new'
from /var/lib/gems/2.3.0/gems/activerecord-5.0.0.rc2/lib/active_record/inheritance.rb:65:in `new'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/reflection.rb:8:in `build_association'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/associations.rb:7:in `build_record'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/associations.rb:25:in `build'
from /var/lib/gems/2.3.0/gems/protected_attributes-1.1.3/lib/active_record/mass_assignment_security/associations.rb:64:in `build'
from (irb):2
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/console.rb:65:in `start'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/console_helper.rb:9:in `start'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/commands_tasks.rb:78:in `console'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
from /var/lib/gems/2.3.0/gems/railties-5.0.0.rc2/lib/rails/commands.rb:18:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'

uninitialized constant ActiveRecord::MassAssignmentSecurity

On an upgrade from Rails 3.2, I get the following error when I start the rails server:

C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/protected_attributes-0.0.1/
lib/active_record/mass_assignment_security/attribute_assignment.rb:35:in `initia
lize_mass_assignment_sanitizer': uninitialized constant ActiveRecord::MassAssign
mentSecurity::AttributeAssignment::ClassMethods::Model (NameError)
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/protected_attr
ibutes-0.0.1/lib/active_record/mass_assignment_security/attribute_assignment.rb:
16:in `block in <module:AttributeAssignment>'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/bundler/gems/rails-
daa7b4e2f0f0/activesupport/lib/active_support/concern.rb:114:in `class_eval'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/bundler/gems/rails-
daa7b4e2f0f0/activesupport/lib/active_support/concern.rb:114:in `append_features
'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/protected_attr
ibutes-0.0.1/lib/active_record/mass_assignment_security.rb:14:in `include'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/protected_attr
ibutes-0.0.1/lib/active_record/mass_assignment_security.rb:14:in `<class:Base>'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/protected_attr
ibutes-0.0.1/lib/active_record/mass_assignment_security.rb:12:in `<top (required
)>'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/protected_attr
ibutes-0.0.1/lib/protected_attributes.rb:3:in `<top (required)>'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler/runtime.rb:68:in `require'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler/runtime.rb:68:in `block (2 levels) in require'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler/runtime.rb:66:in `each'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler/runtime.rb:66:in `block in require'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler/runtime.rb:55:in `each'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler/runtime.rb:55:in `require'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.2.2/
lib/bundler.rb:128:in `require'
    from C:/Sites/shelflives/config/application.rb:7:in `<top (required)>'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/bundler/gems/rails-
daa7b4e2f0f0/railties/lib/rails/commands.rb:83:in `require'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/bundler/gems/rails-
daa7b4e2f0f0/railties/lib/rails/commands.rb:83:in `block in <top (required)>'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/bundler/gems/rails-
daa7b4e2f0f0/railties/lib/rails/commands.rb:80:in `tap'
    from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/bundler/gems/rails-
daa7b4e2f0f0/railties/lib/rails/commands.rb:80:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

I'm not sure why this is happening, but on a lark I deleted the contents the method that was throwing the error:

    def initialize_mass_assignment_sanitizer
      attr_accessible(nil) if Model.whitelist_attributes
      self.mass_assignment_sanitizer = Model.mass_assignment_sanitizer if Model.mass_assignment_sanitizer
    end

The server will boot up after that, but when I try actually assigning values, I get a "stack level too deep" error. Any idea what's going on?

rails 4.2-stable has_many through association ArgumentError: wrong number of arguments (2 for 1) when using protected_attributes, method signature mismatch

I have a problem that seems to be similar to rails/rails#18121

rails: 4-2-stable git
protected_attributes: git master branch

There seems to be another method signature mismatch HasManyThroughAssociation#build_record(https://github.com/rails/protected_attributes/blob/master/lib/active_record/mass_assignment_security/associations.rb#L72), which only takes one argument now, and the subsequent override in protected_attributes(https://github.com/rails/protected_attributes/blob/master/lib/active_record/mass_assignment_security/associations.rb#L72) . Say I have a users table, tasks table, and users_tasks table with has_many :through set up on both sides.

irb(main):001:0> u = User.create name: 'tony'                                                                                                                                                                                                    
=> #<User id: 1, name: nil, created_at: "2015-01-19 07:59:04", updated_at: "2015-01-19 07:59:04">
irb(main):004:0> u.tasks.new name: 'wat'
ArgumentError: wrong number of arguments (2 for 1)
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activerecord/lib/active_record/associations/through_association.rb:95:in `build_record'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/protected_attributes-61e622368d66/lib/active_record/mass_assignment_security/associations.rb:72:in `build_record'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/protected_attributes-61e622368d66/lib/active_record/mass_assignment_security/associations.rb:19:in `build'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/protected_attributes-61e622368d66/lib/active_record/mass_assignment_security/associations.rb:55:in `build'
        from (irb):4
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/railties/lib/rails/commands/console.rb:110:in `start'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/railties/lib/rails/commands/console.rb:9:in `start'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/railties/lib/rails/commands/commands_tasks.rb:68:in `console'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/railties/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/railties/lib/rails/commands.rb:17:in `<top (required)>'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:274:in `require'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:274:in `block in require'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:274:in `require'
        from /Users/tony/src/rails_bug/bin/rails:8:in `<top (required)>'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:268:in `load'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:268:in `block in load'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/bundler/gems/rails-26c293e1d018/activesupport/lib/active_support/dependencies.rb:268:in `load'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/commands/rails.rb:6:in `call'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/command_wrapper.rb:38:in `call'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application.rb:183:in `block in serve'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application.rb:156:in `fork'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application.rb:156:in `serve'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application.rb:131:in `block in run'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application.rb:125:in `loop'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application.rb:125:in `run'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/spring-1.2.0/lib/spring/application/boot.rb:18:in `<top (required)>'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /Users/tony/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        from -e:1:in `<main>'irb(main):005:0>

I have an example repo with a test that will trigger the error:
https://github.com/mcfiredrill/rails_bug
The test is here:
https://github.com/mcfiredrill/rails_bug/blob/master/test/models/user_test.rb#L7

concatenating to hmt causes mass-assignment error with AR 4.1.2.rc1

In ActiveRecord 4.1.2.rc1, I'm seeing mass assignment errors from concatenating to a has_many_through collection like the below; these errors do not occur in 4.1.1.

class Group < ActiveRecord::Base
  ...
  has_many :members, :through => :memberships, :source => :user
end

group.members << user

Standalone reproduction script: https://gist.github.com/seanwalbran/4f8670b2afc5b3f1e912

 1) Error:
BugTest#test_concat:
ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes for Membership: group_id
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_model/mass_assignment_security/sanitizer.rb:60:in `process_removed_attributes'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_model/mass_assignment_security/sanitizer.rb:10:in `sanitize'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_model/mass_assignment_security.rb:346:in `sanitize_for_mass_assignment'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_record/mass_assignment_security/attribute_assignment.rb:58:in `assign_attributes'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_record/mass_assignment_security/core.rb:8:in `init_attributes'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/core.rb:198:in `initialize'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/inheritance.rb:30:in `new'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/inheritance.rb:30:in `new'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_record/mass_assignment_security/reflection.rb:5:in `build_association'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_record/mass_assignment_security/associations.rb:5:in `build_record'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/protected_attributes-1.0.7/lib/active_record/mass_assignment_security/associations.rb:19:in `build'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/has_many_through_association.rb:86:in `build_through_record'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/has_many_through_association.rb:97:in `save_through_record'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/has_many_through_association.rb:64:in `insert_record'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:522:in `block (2 levels) in concat_records'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:389:in `add_to_target'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:521:in `block in concat_records'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:519:in `each'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:519:in `concat_records'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/has_many_through_association.rb:42:in `concat_records'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:153:in `block in concat'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:168:in `block in transaction'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `block in transaction'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/connection_adapters/abstract/database_statements.rb:209:in `within_new_transaction'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `transaction'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/transactions.rb:208:in `transaction'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:167:in `transaction'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_association.rb:153:in `concat'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/has_many_through_association.rb:36:in `concat'
    /Users/swalbran/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.2.rc1/lib/active_record/associations/collection_proxy.rb:972:in `<<'
    ./protected.rb:49:in `test_concat'

undefined method `options_for_through_record'

After upgrade I got:

protected_attributes-1.1.1/lib/active_record/mass_assignment_security/associations.rb:96:in <class:HasManyThroughAssociation>': undefined methodoptions_for_through_record' for class `ActiveRecord::Associations::HasManyThroughAssociation' (NameError)

Bugfixes in master are not yet released

Hi,

We are in the process of migrating our app from Rails 4.0 to Rails 4.1

We encountered the #77 issue, which was fixed in master by the #81 PR

We could require the master branch, but we would rather depend on a stable gem version.

Are you planning to release a new version of the gem soon ?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.