Cannot load such file located in lib directory - ruby-on-rails

I have been trying to set up my work environment on a new computer (ruby 1.9.3.p0 and rails 3.2.6) for the last two days and I keep getting the following error when I try to run rails server or rails console:
application.rb:7:in `require': cannot load such file -- acts_as_loggable/acts_as_loggable (LoadError)
This is what my application.rb looks like:
require File.expand_path('../boot', __FILE__)
require 'acts_as_loggable/acts_as_loggable'
require 'acts_as_abusable/acts_as_abusable'
require 'acts_as_luba/acts_as_luba'
module MyProgram
class Application < Rails::Application
config.active_record.schema_format = :ruby
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib/)
config.autoload_paths += %W(#{config.root}/app/models/game_mechanics)
config.autoload_paths += Dir["#{config.root}/app/admin/"]
config.autoload_paths += Dir["#{config.root}/app/models/"]
config.active_record.pluralize_table_names = true
config.action_view.sanitized_allowed_attributes = ['data-link']
My acts_as_loggable.rb file is located in lib/acts_as_loggable. All my other files load okay, except for the 3 that I left in my application.rb code sample.
If I hardcode the path/directory (see below), my app works.
require './lib/acts_as_loggable/acts_as_loggable'
require './lib/acts_as_abusable/acts_as_abusable'
require './lib/acts_as_luba/acts_as_luba'
Does anyone have any clue what is happening and how I can get my app to work without the hardcoded paths?
Thanks.

Your require is before config.autoload_path.

Related

Renaming workers per requirements of Zeitwerk (Rails 5.2.3 to 6 upgrade)

I have some Sidekiq workers that have a naming convention of like random_api_worker.rb and have the class defined as RandomAPIWorker and it has always worked up until Rails 6. In other cases, I have the classes starting off as class RandomAPIWorker although it's in a few subdirectories, such as app/workers/dir1/dir2/random_api_worker.rb
I have added config.autoloader = :classic to my application.rb file, but this seems to only do the trick if I'm running everything in development. The minute I flip the RAILS_ENV to production, then it starts complaining about worker names.
This brings me to a two questions:
Isn't the config.autoloader = :classic supposed to ignore this, or am I misunderstanding how this works?
Is there a Zeitwerk script available that could essentially upgrade classic worker names in a proper format/hierarchy?
If #1 is false, is there another way to keep my workers with their same names and not have to worry about renaming them to meet the requirements of Zeitwerk?
Here's my application.rb file:
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Vspm
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0
config.autoload = :classic
config.autoload_paths << Rails.root.join('app/workers/sampleworkers/**/')
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
config.enable_dependency_loading = true
config.eager_load_paths += Dir["#{config.root}/lib/custom/**/"]
# Add images and subdirectories to asset pipeline
config.assets.paths << "#{Rails.root}/app/assets/images/severity_icons/"
end
Here's one error (complains about the caps in one of the class names):
ubuntu#c567d17a6700:~/myapp/app$ RAILS_ENV=production rails zeitwerk:check
Hold on, I am eager loading the application.
expected file app/services/pdf_generator.rb to define constant PdfGenerator
Here's the class name defined in that file:
# app/services/pdf_generator.rb
class PDFGenerator
After fixing this, the next error complains about the directory hierarchy not being in the worker's class name:
ubuntu#c567d17a6700:~/myapp/app$ RAILS_ENV=production rails zeitwerk:check
Hold on, I am eager loading the application.
expected file app/workers/shared/random_name_worker.rb to define constant Shared::RandomNameWorker
Here's how the class is mentioned in that file:
# app/workers/shared/random_name_worker.rb
class RandomNameWorker
Isn't the config.autoloader = :classic supposed to ignore this, or am I misunderstanding how this works?
this setting config Rails back to classic mode loader on the whole app, so of course it'll ignore structure name convenient.
you could setup autoload_paths with zeitwerk, your problem is the way you add nested workers directories to autoload_paths
# NOT THIS
config.autoload_paths << Rails.root.join('app/workers/sampleworkers/**/')
# SHOULD THIS
config.autoload_paths << Rails.root.join('app/workers/sampleworkers/')
# OR THIS (if you want to use `**`)
config.autoload_paths += Dir["#{config.root}/app/workers/**/**"]
# REPLACE
config.autoloader = :classic
# BY
config.load_defaults 6.0
Is there a Zeitwerk script available that could essentially upgrade classic worker names in a proper format/hierarchy?
i don't know whether there's a gem support that or not, i haven't seen so far, i do it manually, create module each sub directories, so your worker become something like this Api_Worker::Random
# app/worker/api_worker.rb
module ApiWorker
end
# app/worker/api_worker/random.rb
module ApiWorker
class Random
include Sidekiq::Worker
end
end
If #1 is false, is there another way to keep my workers with their same names and not have to worry about renaming them to meet the requirements of Zeitwerk?
As i said above, you could extend autoload_paths with zeitwerk
config.autoload_paths += Dir["#{config.root}/app/workers/**/**"]
and you still use the name RandomAPIWorker

Rails 5.2 & Bootsnap: NameError while using app/lib file

I just upgraded to Rails 5.2 and have run into the following issues in development mode, while using a class JsonWebToken from my app/lib folder in my ApplicationController.
NameError - uninitialized constant ApplicationController::JsonWebToken:
Following the directions listed here, I have the following notable things:
I'm using bootsnap that comes by default with Rails 5.2
I no longer have a require at the top of ApplicationController since files within the app folder seem to be auto-required.
In my development.rb, I have config.eager_load = false.
In my application.rb, I have the following eager and auto loading code:
autoloads lib & policy folder during production
config.eager_load_paths << Rails.root.join('lib')
config.eager_load_paths << Rails.root.join('policies')
#autoloads lib & policy folder during development
config.autoload_paths << Rails.root.join('lib')
config.autoload_paths << Rails.root.join('policies')
If I remove bootsnap, then I have to add require 'JsonWebToken' at the top of ApplicationController, and then everything works. Bootsnap didn't like that require statement at the top.
I am not sure what is the right way to be creating or using your own classes in Rails 5.2, and to set up so that they are loaded properly in both development and production. I have gone through the Rails docs, but am extremely unclear.

Rails auto loading files from wrong location

I see lots of
LoadError: Unable to autoload constant SomeModule::MyJob expected /app/lib/some_module/my_job.rb to define it.
errors in my Rails 5.2.0 application. The part I don't understand is, why it would look inside app/lib/, since it's defined to be loaded like this in the application.rb:
config.autoload_paths << Rails.root.join('lib')
So I would expect it to load from /lib (where the module in question is located). So why is it looking inside the /app directory and how can I change it?
Change
config.autoload_paths << Rails.root.join('lib')
to
config.autoload_paths += Dir["#{Rails.root}/lib/*"]
it should work.

require bindata in ruby on rails application

I have a set of files that are in the lib directory of a Ruby on Rails application.
I have a model that needs to use these files. In my model I have the following:
require_relative '../../some_path_to_file_without_extention'
(Side note; I would love to know a way to require all the files, instead of require_relative for each file).
The file that I require_relative has the following require in it.
require "bindata"
When I try to access functions from the require_relative file I get the following error:
LoadError: cannot load such file -- bindata
This is happening for other gems that are being required in the set of files as well. I just chose bindata as an example.
I have bindata in my Gemfile. When I run bundle show bindata it shows me the path to bindata.
I even put require 'bindata' in my model, but it gave me the same load error.
How do I stop the LoadError?
Any help would greatly be appreciated.
Update 1
When I run bundle show . I get the following:
Gems included by the bundle:
...
* bcrypt (3.1.11)
* bindata (2.3.4)
...
Then in the console, requiring bcrypt works but bindata does not.
irb(main):002:0> require 'bcrypt'
=> true
But bindata does not.
irb(main):003:0> require 'bindata'
LoadError: cannot load such file -- bindata
Update 2
Ok so I know is has to be something with how I am loading my rails environment.
bundle exec irb
irb(main):001:0> require 'bindata'
=> true
Update 3
So I went back a few git commits and keep trying to add the gems and see if they would load in my rails console. I went back far enough were it did. Did not know what was different. However, I also noticed when my spring server was restarted then my gems would load in my rails console.
To require all the files in the lib folder, add config.autoload_paths << Rails.root.join('lib') to your application.rb, this answer can help you: https://stackoverflow.com/a/19650564/3739191
Now,
require 'bindata'
should work :)

Cannot generate a Pages controller in the Rails 3 tutorial

I am working through the Michael Hartl Rails 3 tutorial, and I am currently on Chapter 3. The tutorial asks me to generate a Pages controller with actions for a Home page and a Contact page using the command line: "$ rails generate controller Pages home contact".
This is the output I get:
ruby 1.9.2p290 (2011-07-09) [i386-mingw32]
C:\Users\abcd\rails_projects2\sample_app>rails generate controller Pages home
contact
C:/Users/abcd/rails_projects2/sample_app/config/application.rb:8:in `require':
no such file to load -- sprockets/railtie (LoadError)
from C:/Users/abcd/rails_projects2/sample_app/config/application.rb:8:
in `<top (required)>'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.9/lib/rails/comman
ds.rb:15:in `require'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.9/lib/rails/comman
ds.rb:15:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
The contents of my config/application.rb file:
require File.expand_path('../boot', __FILE__)
# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require *Rails.groups(:assets => %w(development test))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module SampleApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
end
end
I have also discovered that when I try to run the command line "rails server", I get a similar error message. I don't know if this information is useful.
Thank you!
It looks like the tutorial is using Rails 3.0.9, but you've created your application using a later version of the Rails gem.
sprockets was added in version 3.1. Even though you've updated your Gemfile to specify Rails 3.0.9, the code that was generated when you ran rails new sample_app is expecting Rails 3.1 gems to be available (i.e. simply changing the Gemfile isn't enough to change the Rails version of the application).
You could try simply commenting out the reference to sprockets in your application.rb file, but even if that works for now it's likely there'll be other differences that'll cause errors later.
Your best bet is probably to start from scratch, but make sure you're using Rails 3.0.9. If you're using RVM, you could create a new gemset and install 3.0.9 into it, then use that gemset.
Alternatively, when you create the application specify the version of the gem you want in the command:
rails _3.0.9_ new sample_app
If you use this second method, then after you've created the application, simply using rails by itself to issue commands (like generate) should be okay, as Rails does some magic to determine the version of the app and use the right gem version, even if a later version is installed - you don't need to use rails _3.0.9_ all the time.
in your config/application.rb file, try to uncomment the "sprockets" line like this:
# require "sprockets/railtie"
Then check if it works afterwards... that should do the trick...
But if not, please check your Gemfile, it should look something like this:
# gem "rails", "~> 3.1.0" # or "3.0.9"
gem "rails" , "3.0.9"
gem 'sqlite3', '1.3.3' # or whatever DB you use
If that still doesn't help, check which version of sprockets you have installed:
in a shell, do a:
$ gem list | grep sprock
sprockets (2.0.0.beta.10)

Resources