Closed mehagar closed 3 years ago
Which line of protected_attributes_continued
accesses the database in your error stacktrace?
You can also use:
Audited.config do |config|
if Audit.table_exists?
config.audit_class = ::Audit
end
end
###
class Audit
if Audit.table_exists?
attr_protected :customer_id
end
end
Here is the stack trace:
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `connect'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `initialize'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/mysql2_adapter.rb:22:in `new'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/mysql2_adapter.rb:22:in `mysql2_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:830:in `new_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:874:in `checkout_new_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:853:in `try_to_checkout_new_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:814:in `acquire_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:538:in `checkout'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:382:in `connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:1033:in `retrieve_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_handling.rb:118:in `retrieve_connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_handling.rb:90:in `connection'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/model_schema.rb:324:in `table_exists?'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/attribute_methods/primary_key.rb:99:in `get_primary_key'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/attribute_methods/primary_key.rb:87:in `reset_primary_key'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/attribute_methods/primary_key.rb:75:in `primary_key'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/attribute_methods/primary_key.rb:89:in `reset_primary_key'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/attribute_methods/primary_key.rb:75:in `primary_key'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/protected_attributes_continued-1.7.0/lib/active_record/mass_assignment_security/attribute_assignment.rb:15:in `attributes_protected_by_default'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/protected_attributes_continued-1.7.0/lib/active_model/mass_assignment_security.rb:333:in `block in protected_attributes_configs'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/protected_attributes_continued-1.7.0/lib/active_model/mass_assignment_security.rb:222:in `protected_attributes'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/protected_attributes_continued-1.7.0/lib/active_model/mass_assignment_security.rb:126:in `block in attr_protected'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/protected_attributes_continued-1.7.0/lib/active_model/mass_assignment_security.rb:125:in `each'
/Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/protected_attributes_continued-1.7.0/lib/active_model/mass_assignment_security.rb:125:in `attr_protected'
Does the following monkey patch work for you?
ActiveRecord::MassAssignmentSecurity::ClassMethods.module_eval do
def attributes_protected_by_default
if table_exists?
default = [ primary_key, inheritance_column ]
default << 'id' unless primary_key.eql? 'id'
default
else
[]
end
end
end
It does not, because the call to table_exists?
itself tries to connect to the database (shown in this stack trace):
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/mysql2_adapter.rb:12:in `mysql2_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:830:in `new_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:874:in `checkout_new_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:853:in `try_to_checkout_new_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:814:in `acquire_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:538:in `checkout'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:382:in `connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:1033:in `retrieve_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_handling.rb:118:in `retrieve_connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/connection_handling.rb:90:in `connection'
from /Users/michaelhagar/.rvm/gems/ruby-2.7.2@sa/gems/activerecord-5.2.4.4/lib/active_record/model_schema.rb:324:in `table_exists?'
How about the following
ActiveRecord::MassAssignmentSecurity::ClassMethods.module_eval do
def attributes_protected_by_default
begin
default = [ primary_key, inheritance_column ]
default << 'id' unless primary_key.eql? 'id'
default
rescue ActiveRecord::NoDatabaseError
[]
end
end
end
Yes, that works.
Ok this should now be fixed in master.
v1.8.0 is now released which contains this fix.
In Rails 5.2, a new behavior described here will cause Rails configs to be loaded for all rake tasks.
In our case, if the database has not yet been created (before
rake db:create
) has been run, and then we runrake db:create
, this is what happens:we are using the
audited
gem and using its initializer to configure the class to use for auditing:So that class is loaded, which has this code:
The
attr_protected
call connects to the database to determine the primary key of the model to use as a default id. But since the database has not yet been created, it fails. This creates a catch-22 where we cannot create the database, because the rake task to create it fails because there is no database.Ideally there would be a way to opt out of the behavior that by default connects to the database to determine the primary key.