Rails 3, app/lib not loaded with rspec - ruby-on-rails

I have a controller "A" which requires a file in a subdirectory of app/lib (ex: app/lib/a_folder/my_class.rb).
So I did something like this :
require 'a_folder/my_class'
class AController < ApplicationController
# Some stuff using MyClass
end
It works well when I use the application, but doesn't work when I launch RSpec.
This is how my RSpec file looks:
require 'spec_helper'
require 'lib/import_functions' # Rails.root/spec/lib/import_functions.rb
RSpec.describe AController, type: controller do
# My tests routines
end
When I start rspec it tells me the require in the controller file doesn't found the file (`require': cannot load such file), while it works well when I start the app.
I've added a puts $LOAD_PATH just before the require and it appears that Rails.root/app/lib is not present.
I use Rails 3.2 and rspec-rails 3.2.
Does anyone have any idea why it happens and how to fix it please ?
Thank you for your future answers.

lib files are not auto loaded. You can put the following configuration in your application.rb, it has a problem also it will load all files under lib directory.
config.autoload_paths += "#{Rails.root}/lib/"
Or you can load your lib files in your RSpec as following code
require_relative "../../lib/a_folder/my_class.rb"
or
require 'lib/a_folder/my_class.rb'

Related

Where should i place helper method for rspec test in Rails6?

I have helper method for rspec test like this :
<bla_bla_helper.rb>
Module blabla
def bla
end
end
Where should i place this module?
This module is only for rspec test.
Past version of Rails used spec/support directory, should i use this directory?
In RSpec you use spec/support to place the helpers, matchers, shared contexts etc that your specs need. This path is added to the load path so you can simply do require 'foo' in your specs to require spec/support/foo.rb.
Some projects use a glob in spec/spec_helper.rb to require all the files in the spec/support directory.
This is just an RSpec convention that has nothing to do with Rails, so the practice isn't going to change with Rails versions.
I usually place mine inside spec/support/helpers and include it in the configuration via rails_helper.
Here's an example of including the devise API auth helper that I am using for my application.
config.include DeviseApiAuthHelper, type: :controller
Yes you can continue using spec/support directory.

rails: autoload files inside engine's lib directory

I am working on this rails application with an engine which is sort of sub application adding some more routes to my existing application.
The concept is so powerful, thanks to rails.
But I am facing this weird challenge to autoload file changes inside my engines lib directory in development mode. Every time I make a change inside app directory of engine be it model or controller , it works flawlessly, but no changes to any files under lib directory get's picked up. Is there a way I can do this ? Thanks for your help.
According to Rails::Engine docs you can autoload paths like-
class MyEngine < Rails::Engine
# Add a load path for this specific Engine
config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)
initializer "my_engine.add_middleware" do |app|
app.middleware.use MyEngine::Middleware
end
end
If you don't want to autoload, you can directly require the file in your class with the require statement-
require 'my_engine/my_object'
class MyModel < AR::Base
...
end
This will work because your Engine is already loaded in your app, so you can access libs inside of it.
Put the following code in your config/application.rb
config.eager_load_paths += ["#{Rails.root}/lib"]
If you want this only in development mode use the following
config.eager_load_paths += ["#{Rails.root}/lib"] if Rails.env.development?

Cannot access models from /lib in Rails

I make a script to try some functions. But I cannot use models in lib. Interesting is, that I already have an lib, and there it works fine with the mostly same code(?).
// script/tags.rb:
require File.expand_path('../../config/application', __FILE__)
require 'company_tags'
host = ARGV[0] || 'team1.crm.tld'
c = CompanyTags.new(host)
c.run
// lib/company_tags.rb
class CompanyTags
def initialize(host)
#site = Site.where(host: host).first
end
def run
comp = #site.companies.first
comp.tag_list.add("tag1")
comp.general_list.add("tag_general")
comp.save!
p comp.tag_list
end
end
Error: /lib/company_tags.rb:3:in `initialize': uninitialized constant CompanyTags::Site (NameError)
You need to require the environment, not the application.
require File.expand_path('../../config/environment', __FILE__)
require 'company_tags'
The environment will load all the dependencies, including the application, and it will bootstrap the application.
Just an idea, but try changing Site.where(host: host).first to ::Site.where(host: host).first. Putting the :: in front, causes ruby to look for Site in the global namespace instead of as a constant defined in CompanyTags.
You can add a simple configuration to config/application.rb:
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Check this question out for more details.
In my previous answer, I thought you were running rails console. Your main issue is that the Site class is not required. Here is how requiring files to your classes work.
Through the require_all function
require_all(MY_CLASSES_DIRECTORY)
Or by requiring each class manually:
require 'Class_NAME.rb'
Notice that the Site class is not required anywhere.
For more details, check this link

How to require some lib files from anywhere

I'll explain my situation.
Here is my file tree in my rails application :
lib/my_module.rb
require 'my_module/my_file'
module My_module
end
lib/my_module/my_file.rb
class Tweetag::Collector
(...)
end
I've made a ruby script that I've put in config/jobs/
I really don't understand how I am supposed to require the file my_file.rb in this file.
require '../../my_module/my_file.rb'
It gives me `require': cannot load such file
Same error with just require 'my_module' which is what I do in my controllers...
Someone here to explain to me ? Thanks a lot
You can autoinclude everything under the lib folderand avoid these problems:
Type this your file in config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
If you want to require only a specific file then,
do something relative to Rails root like this
for example: --
lib/plan.rb
module Plan
...some code...
end
and if you want to require it only in some model, say app/models/user.rb
do in user model
require "#{Rails.root}/lib/plan"
class User < ActiveRecord::Base
include Plan
end
if you want it to be available everywhere
one solution is given by #VecchiaSpugna
or you can create a ruby file in config/initializers folder
and require all file over there one by one
OR
try this
require '../../my_module/my_file'
instead of
require '../../my_module/my_file.rb'
You don't need to specify extension for a file in require.
I think there are two solutions.
1) Add the lib path to the search path.
In ruby:
$:.unshift('../../my_module/lib')
Then you can require 'my_module.rb'
I think Vecchia Spugna answer is the rails-version of my ruby-answer. (I'm not familiar with rails).
2) Another solution:
In your lib/my_module.rb you require my_file. This file is located relative to your my_module.rb? Then use require_relative:
require_relative './my_module/my_file'
Just chiming in because it took me forever to figure this out because very little solutions worked.
• I had to use plain old require. I put it in the config/application.rb file.
patching_file_path = File.expand_path("./lib", Dir.pwd)
Dir[patching_file_path+'/*.rb'].each {|file| require file }
• I also put a temporary puts "I'm Working! in the file I'm trying to require so I can check the console to see if it's actually loading.
• Also, if you're using spring loader, before you start your console you should do bin/spring stop in your terminal before you start your rails console. Otherwise, it won't load new files.
Similar to require_relative,
# inside lib/my_module.rb
require File.expand_path('./my_module/my_file', File.dirname(__FILE__))
This expands the path of current file directory and add the relative file path to be required.

No such file to load, Model/Lib naming conflict?

I'm working on a Rails application. I have a Module called Animals. Inside this Module is a Class with the same name as one of my Models (Dog).
show_animal action:
def show_animal
require 'Animals/Bear.rb' #Works
require 'Animals/Dog.rb' #Fails
end
So the first require definitely works, the seconds fails.
MissingSourceFile (no such file to load -- Animals/Dog.rb):
I noticed that Dog.rb is the same file name as one of my models, is that what's causing this? I'm using Webrick.
Try using the full path:
require File.join(RAILS_ROOT, 'lib', 'Animals', 'Dog.rb')

Resources