james2m / canard

Makes role based authorization in Rails really simple. Wraps CanCan and RoleModel up with a smattering of syntactic sugar, some generators and scopes.
MIT License
125 stars 28 forks source link

Heroku, devise, and canard fails on rake assets:precompile #11

Open cforcey opened 11 years ago

cforcey commented 11 years ago

With Rails 4.0 beta1, devise loads the user model which, in turn, loads canard which checks it for a role matrix. This is fine if the database exists, but as many of us know from painful experience Heroku does not bring the database up before running the precompile. As a result you see:

Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       could not connect to server: Connection refused
       Is the server running on host "127.0.0.1" and accepting
       TCP/IP connections on port 5432?
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:771:in `initialize'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:771:in `new'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:771:in `connect'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:493:in `initialize'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:41:in `new'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:41:in `postgresql_c
onnection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:446:in `new_c
onnection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:456:in `check
out_new_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:427:in `acqui
re_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `block
 in checkout'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `check
out'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:273:in `block
 in connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:272:in `conne
ction'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:552:in `retri
eve_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_handling.rb:79:in `retrieve_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_handling.rb:53:in `connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/model_schema.rb:203:in `table_exists?'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/canard-0.4.1/lib/canard/adapters/active_record.rb:30:in `active_record_table?'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/canard-0.4.1/lib/canard/adapters/active_record.rb:35:in `has_roles_mask_accessors?'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/canard-0.4.1/lib/canard/user_model.rb:74:in `acts_as_user'
       /tmp/build_2sfjhhr6toicw/app/models/user.rb:12:in `<class:User>'
       /tmp/build_2sfjhhr6toicw/app/models/user.rb:1:in `<top (required)>'

The workaround that got Heroku back up and running was to only run the canard helper if the connection is present.

  # must test for the connection because of a precompile problem on Heroku 
  acts_as_user :roles => [:timekeeper, :admin] if ActiveRecord::Base.connected?

Not sure if anything can be done on the code side but if it was built in to the matrix check that would help. Possible? Necessary? Thanks so much for the wonderful work on this gem. I rolled my own at first and then appreciated the hard work that went into this gem all the more.

james2m commented 11 years ago

This shouldn't be too hard for me to fix. It sounds like a similar issue to one I fixed in authlogic.

I'm travelling right now, so will fix when I get a little downtime. Or happy to get pull requests ;)

yawo commented 10 years ago

on Heroku, when you put the if ActiveRecord::Base.connected? you can get undefined method admin? error as User got not initialized at all with roles.

A fix was to move the line from add this to config/application.rb :

initializer "canard.initialize_roles",:after => "active_record.log_runtime" do |app| User.acts_as_user :roles => [:manager, :admin,:superadmin] end