canard
canard copied to clipboard
Heroku, devise, and canard fails on rake assets:precompile
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.
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 ;)
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