Rails on Heroku: NameError: uninitialized constant ApplicationPolicy - ruby-on-rails

While deploying my Rails API app to Heroku, my build is failing with the error below:
-----> Detecting rake tasks
sh: 2: Syntax error: Unterminated quoted string
sh: 2: Syntax error: Unterminated quoted string
!
! Could not detect rake tasks
! ensure you can run `$ bundle exec rake -P` against your app
! and using the production group of your Gemfile.
! rake aborted!
! NameError: uninitialized constant ApplicationPolicy
/tmp/build_64dbe116b1bd38f520ae98d49690e476/sdotapi-86210153dc2b588aa7b0dc9a60799f5090c76f46/app/policies/user_setting_policy.rb:1:in `<top (required)>'
Now, the problem is that I don't see this NameError error on my local development box. It would seem to suggest that somehow the path for my Pundit policies isn't getting loaded on Heroku but are happening on local box. But I am not sure why:
Here is the relevant part of my application.rb looks like:
config.autoload_paths << Rails.root.join('lib')
Dir[Rails.root.join('app/policies/*.rb')].each &method(:require)
The line where the error was:
class UserSettingPolicy < ApplicationPolicy
Both the policy files live in app/policies.
Any ideas on what might be going on would be super appreciated!

Found the problem finally. The policy files were getting loaded one by one in the above code and hence had to change it to below for Rails to load entire directory at once it seems.
config.autoload_paths += Dir[Rails.root.join('app', 'policies', '*.rb')]
# earlier it was Dir[Rails.root.join('app/policies/*.rb')].each &method(:require)
On a different note, the above lines in config/application.rb ended up being:
config.autoload_paths += Dir[
Rails.root.join('app', 'policies', '*.rb'),
Rails.root.join('app', 'lib', '*.rb')
]
Notice the change for lib, due to changes in autoloading in Rails 5. See here for more details: https://stackoverflow.com/a/40019108

Related

rake causes compilation of assets using production.rb in development mode

I am upgrading to rails 7.0.3.1 from rails 6.1.6.1. Whenever I run a rake task there is an exception generated. For example with this simple rake task
namespace :tests do
task temp: :environment do
puts "Environment is #{Rails.env}"
end
end
if I run rake tests:temp then I see the following
Precompiling assets for local
precompile asset_host is
rake aborted!
KeyError: key not found: "APPLICATION_HOST"
/Users/myname/myapp/config/environments/production.rb:8:in `fetch'
...
Tasks: TOP => environment
(See full trace by running task with --trace)
[master c970ac9] Add precompiled assets for local
2 files changed, 1593 insertions(+), 1840 deletions(-)
...
Environment is development
I can provide the full trace if requested. Note that after the exception, the rake test does work successfully. Also the code is making a git commit to the effect Add precompiled assets for local. The environment variable APPLICATION_HOST is not set in the development environment, because it is only needed in production.
I was not seeing this problem in rails 6. What is causing this?
It turns out that I have a method defined in a Mixin which looks like this
def precompile_assets(target: 'local)
puts "Precompiling assets for #{target}"
...
system("RAILS_ENV=production RAILS_HOST_PATH=#{asset_host} rake assets:precompile")
end
This was only meant to be used in rake tasks used for deployment. It looks like somewhere in Rails 7 there is another method with the same name, which is being overwritten. The quick solution is rename the method so it does not clash. The longer solution is refactor so as it is not a Mixin.
I guess all those articles about the dangers of Mixins were right.

NameError: uninitialized constant on Heroku

I have a Rails 5 application with some modules/classes located under /lib. In development I can access those through the rails console like so:
irb(main):001:0> MyClass.do_something
In Production on Heroku I get this:
irb(main):001:0> MyClass.do_something
NameError: uninitialized constant MyClass
As you might have guessed I autoload the /lib directory in my application.rb:
config.autoload_paths << Rails.root.join('lib')
However, the most curious thing about this is, that I can access this class from rake tasks. So something like this works fine:
task do_something: :environment do
MyClass.do_something
end
Which tells me that the class is present on Heroku.
Any ideas?
Rails doesn't autoload in production for thread safety, instead eager loading application constants. You can fix your issue by using the eager_load_paths method instead.
config.eager_load_paths << Rails.root.join('lib')
If you still want to autoload in development you can make it conditional
load_path_strategy = Rails.env.production? ? :eager_load_paths : :autoload_paths
config.public_send(load_path_strategy) << Rails.root.join('lib')
If you really need autoloading of this directory in production you can set enable_dependency_loading to true.
config.enable_dependency_loading = true
config.autoload_paths << Rails.root.join('lib')
See this blog post for more explanation.
I have been puzzled why all of my objects were uninitialized constant in console on heroku in production. In my local production, they were fine.
Turns out that the problem was that I was running: "heroku run console" not "heroku run rails console".
Worth noting that when you access console from the heroku website, the same problem occurs there too. Wasted a lot of time on this.

Ruby Rails app: After deleting OmniAuth gem and omniauth.rb, OmniAuth unitialized constant and rake aborted when attempt deploy

Resolved --> use git commit -A or git commit . in correct directory
What happened before:
I included OmniAuth gem in Gemfile, created omniauth.rb in config/initializer folder, used $bundle install.
I realized I didn't want to use the OmniAuth gem so I removed its line from the Gemfile and deleted the omniauth.rb file.
I've also removed the following line from the config/application.rb file just in case:
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
I ran $bundle update in hopes of updating everything.
Now:
App does work on local server, but when I try to deploy to heroku with $git push heroku, the deployment aborts and part of the resulting message is:
Running: rake assets:precompile
rake aborted!
uninitialized constant OmniAuth
/tmp/build_34578113-b133-4234-b473-3cd6bc4872ca/config/initializer/omniauth.rb:1:in >`<top (required)>
Tasks: TOP => environment
(See full trace by running task with --trace)
I've checked and there is no omniauth.rb file in my config/initializer folder, and no swap versions either.
Does anyone know why the system still thinks OmniAuth is still there and what can I do to get rid of it? Might I have missed something? Does anyone have suggestions?

Heroku not running migrations due to ruby module

I am unable to run migrations in Heroku, which I believe is due to a module I created in my lib directory. After executing the command heroku run rake db:migrate I receive the below error:
uninitialized constant ApplicationController::PgTools
/app/app/controllers/application_controller.rb:4:in <class:ApplicationController>
Line 4 of the Application controller is include PgTools, which is there to gain access to methods within the PgTools module I created.
Despite the heroku migration failing, I am able to run rake db:migrate in my local dev environments without fail (please note that both environments utilize postgres databases).
I also have the following two lines in my application.rb file
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
I resolved the error by renaming Pg_Tools.rb to pgtools.rb and modifying all include PgTools statements to include Pgtools
Links that I used in the troubleshooting process are shown below
Rails 3 library not loading until require
http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

rake db:migrate returns no such file to load -- rake/dsl_definition (I've searched and tried adding require 'rake/dsl_definition')

My hair is all gone and I'm about to throw my new macbook through the window.
I am trying to execute the famous db:migrate command and I get the following:
rake aborted!
no such file to load -- rake/dsl_definition
I am using rake 0.8.7...it's installed and included in my gemfile. I didn't have require 'rake/dsl_definition' in my rake file and I was getting the famous uninitialized-constant error. Now that I have added require 'rake/dsl_definition' to my rake file I get the error above. Anyyyyy ideas...I have searched and tried a million things with no luck... My migrations worked 2 days ago, now suddenly they don't. I have uninstalled rake 0.9.2 and also did a few other thing suggested in the link below, but nothing worked.r
How to fix the uninitialized constant Rake::DSL problem on Heroku?
heroku rake require 'rake/dsl_definition' fix not working + breaking local rake
How to fix the uninitialized constant Rake::DSL problem on Heroku?
Having rolled back your rake to 0.8.7, you need to remove the require rake/dsl-definition line from your rakefile. You only get the uninitialised constant error with later rakes.

Resources