Uninitialized constant while trying to include helper module - ruby-on-rails

The module that I am trying to include is located here:
test/unit/helpers/test_helpers.rb
Looks like:
module TestHelpers
end
I am trying to include it in:
test/unit/app/models/abc.rb
class Abc < ActiveSupport::TestCase
include TestHelpers
end
gives the following error:
Error executing test/unit/app/models/abc.rb uninitialized constant
Abc::TestHelpers
Any ideas why this might be happening?

To include a module into your class, you need to require that file.
require 'test_helpers'
Add this line at the top of your model class.

Related

Ruby - NameError: uninitialized constant. Using class from a different module

I have these 2 files in a large system, both are located in PackA
people.rb
module People
class HobbyValueObject
end
end
job.rb
module People
class Job
end
class CityValueObject
end
end
I am trying to use CityValueObject in a different module like this,
Module is in PackB
work.rb
module Profile
class Work
....
def calculateTaxes
...
a = People::CityValueObject....
end
end
end
But it's giving me an error saying,
NameError: uninitialized constant People::CityValueObject
Did you mean? People::HobbyValueObject
Why is not being able to fine CityValueObject but can find HobbyValueObject just fine?
How do I make it find the object that I am intending to use?
I am not explicitly declaring any requires or includes
I was able to resolve this by adding require at the top while using full path file name.
require './packs/people/app/public/people/job'

Use anonymous class generated by struct in ruby tests

So, here we have a file with struct,
module CoreDomain
Corporation = Struct.new(...)
end
and we have such a test file,
require 'test_helper'
module CoreDomain
class CorporationTest < ActiveSupport::TestCase
def test_corporation_struct_creation
corp_struct = CoreDomain::Corporation.new(...)
assert_equal ..., ...
end
end
end
when I trying to execute the test I get this error.
NameError: uninitialized constant CoreDomain::Corporation
Question - where I am getting wrong?
What I think is going actually going on here is that you're fooling the autoloader.
Since your test is nested inside module CoreDomain when you get to CoreDomain::Corporation.new(...) it won't trigger the autoloader to start looking for the CoreDomain constant. The classic autoloader worked by hacking its way onto Object.const_missing so was very prone to these kind of errors.
The solution is to just reference the constant before you reopen the module:
require 'test_helper'
CoreDomain::Corporation # take that you stupid autoloader!
module CoreDomain
class CorporationTest < ActiveSupport::TestCase
def test_corporation_struct_creation
corp_struct = Corporation.new(...)
assert_equal ..., ...
end
end
end
Or just remove the test class from the module.
Maybe there was some misunderstanding, but all I need to do is to add this line
require_relative '../../core/domain/corporation.rb'
to the top of test_corporation.rb file

Accessing helpers and models from rails engine initializer

I'm trying to make a Ruby on Rails engine, and I want the initializer to be able to have access to the helpers and models.
I'll write below an example, part of the code, and the error that I have. It may not be the recommended way, because I can see that in some cases I'm repeating myself, but it's the first engine I make.
file lib/my_engine/engine.rb
module MyEngine
require 'my_engine/functions'
class Engine < ::Rails::Engine
isolate_namespace MyEngine
config.autoload_paths += %W( #{config.root}/lib )
end
class GlobalVars
attr_accessor :foo
def initialize
#foo = MyEngine::Functions.new
end
end
class << self
mattr_accessor :GLOBAL
mattr_accessor :USER_CONFIG
self.GLOBAL = MyEngine::GlobalVars.new
# add default values of more config vars here
self.USER_CONFIG = 'default config'
end
def self.setup(&block)
yield self
end
end
file lib/my_engine/functions.rb
module MyEngine
require '../../app/helpers/my_engine/options_helper'
class Functions
include MyEngine::OptionsHelper
attr_accessor :some_link
def initialize
#some_link = get_option('dummy')
end
end
end
There is also a controller named OptionsController in app/controllers/my_engine, and OptionsHelper in app/helpers/my_engine/options_helper.rb:
module MyEngine
module OptionsHelper
def get_option(name)
MyEngine::Option.new
end
end
end
When I try to run the dummy application, this error occurs:
/app/helpers/my_engine/options_helper.rb:4:in `get_option': uninitialized constant MyEngine::Option (NameError)
If I change to just Option.new, I have this error:
/app/helpers/my_engine/options_helper.rb:4:in `get_option': uninitialized constant MyEngine::OptionsHelper::Option (NameError)
For ::MyEngine::Option.new, I have:
/app/helpers/my_engine/options_helper.rb:4:in `get_option': uninitialized constant MyEngine::Option (NameError)
For ::Option.new, I have:
/app/helpers/my_engine/options_helper.rb:4:in `get_option': uninitialized constant Option (NameError)
The dummy application has nothing in it. All helpers and models defined above are in the engine.
Before this, I had other errors because it couldn't access the helper, or the Functions class. I had to add require and include to make it work even if they are placed in the same directory. Also, to work, I had to move GlobalVars from its own file inside engine.rb.
Can somebody show me what I'm doing wrong?
After I used required for every class, I ended with ActiveRecord::ConnectionNotEstablished, and it seems that not everything is loaded and available at that point when the GLOBAL object is created.
So I moved the code that was using the models in a separate init method. Then, I added an after initialize event:
config.after_initialize do
MyEngine.GLOBAL.init
end
I see a possible problem: because you are inside module MyEngine it might be possible that actually rails is looking for MyEngine::MyEngine::Option, so I see two approaches:
just write Option: this will look for MyEngine::Option
write ::MyEngine::Option this will look in the global namespace and find MyEngine::Option
Secondly, if that does not help, even though your path seems correct, but you can always explicitly require "my_engine/option" at the top of the file. I am not entirely sure the autoloading in an engine works in quite the same way, and I tend to, in my engine file, require almost everything (to make sure it works).
In my engine.rb I do
require_relative '../../app/models/my_engine/option'
maybe this will help, but it is not a nice solution.

Using Watir and uninitialized constant Watir::RSpec::Core

I am trying to create a custom rspec formatter using Watir and got this error while executing the class. I have never used Watir before. Do I need some special gems for it?
Error: uninitialized constant Watir::RSpec::Core (NameError)
My code:
require 'rspec/core/formatters/html_formatter'
module Watir
class RSpec
class CustomFormatter < RSpec::Core::Formatters::HtmlFormatter
end
end
end
The exception is occurring because of the class that the CustomFormatter is trying to inherit from. Due to the location, it is look for the RSpec::Core::Formatters::HtmlFormatter class within the scope of the Watir::RSpec class.
Usually custom formatters are done as:
require 'rspec/core/formatters/html_formatter'
class CustomFormatter < RSpec::Core::Formatters::HtmlFormatter
end
You do not need to put it in a Watir::RSpec space.

undefined method `new' for Test:Module

Hello I have a problem of conflict of the namespace. I have a model: Test and controller TestsController. server displays an error
undefined method `new' for Test:Module
I read this question rails models
added to the model Test in module UserTest
module UserTest
class Test < ActiveRecord::Base
....
end
end
and added to the controller
class TestsController < ApplicationController
def new
#test = UserTest::Test.new
#test.questions.build
#title = "New test"
end
...
end
server shows an error: uninitialized constant TestsController::UserTest
after reading more I realized that probably need to add require or include a controller. Only I do not understand how to do it. please tell me.
Never rename a model to the same name of the project. You will get a message like this:
undefined method `new' for Example:Module
The project module priority precedes on the call.
The convention in Rails is to convert your Class name in file and your module name in directory. So if you put your UserTest::Test class in test.rb file in your app/model directory, the autoload failed to get your class. Because search on app/model/user_test/test.rb file.
So you can "force" the require in your Controller by adding a require in top of your file. The require if you put your class in your test.rb is : require 'test.rb'
To know how define your require is to think the LOAD_PATH of your application add app/model directory. So all inside can be add directly by requiring the directory name and file name.

Resources