i am writing gem for my Rails app which calculates some stuff and uses class and modules.
Here is file structure.
root
->lib
-->finances
--->version.rb
--->finances.rb
--->calculator
----->formulas.rb
--->finalize
---->schedule.rb
-->finances.rb
Now root/lib/finances.rb
require "finances/version"
require "finances/finances"
require "finances/finalize/schedule"
require "finances/calculator/formulas"
root/lib/finances/calculator/formulas.rb
module Calculator
module Formulas
def method
end
end
end
root/lib/finances/finalize/schedule.rb
module Finalize
class Schedule
include ::Calculator::Formulas
end
end
but I get uninitialized constant Calculator (NameError)
if i try to just use
::Calculator::Formulas.method
it throws NoMethodError (undefined methodmethod' for Calculator::Formulas:Model):`
What exactly i am doing wrong. I cant seem to work around this. Could anyone help.
You try to use method as Formulas 'module method', while you defined it as regular instance method. So it should be called on RepaymentSchedule instance:
rs = RepaymentSchedule.new
rs.method
Also, you need to make sure your loading order is correct. Here, you should require file containing Formulas module before you load Schedule class, otherwise you get uninitialized constant error.
Related
I'm trying to create a gem, my gem requires a different gem that I have added into the gemspec.
My issue is when I try to call a method inside the code, ruby automatically adds the module namespace to the method I am calling, then I get an uninitialized constant error. I put a basic example of what is going on below.
lib/example_gem.rb
module FooModule
def bar
# this is the method I am trying to run
BAZ::Request.execute(123)
end
end
class Test
include FooModule
end
x = Test.new
x.bar
=>>>>>>>> uninitialized constant FooModule::Baz (NameError)
I'm not trying to call FooModule::Baz, I want to call BAZ::Request.execute(123). Any help would be appreciated
Try:
::BAZ::Request.execute(123)
The keyword is "constant lookup operator". I assume BAZ isn't wrapped into another class or module, so you need to look for it on the topmost level. Therefore you prepend ::.
And now you understand why the request (BAZ::Request) needs to be within BAZ.
I have a module
lib/Basicstats.rb (module Basicstats ...etc. end)
I am importing this into a model
class Vote < ActiveRecord::Base
include Basicstats
#additional class code etc.
end
I grep-d for the module and 'Basicstats' is only referenced in Basicstats.rb and app/model/vote.rb.
This works fine for my local development. But during my Heroku deployment I am getting this error and it can't seem to recognize the module? (I'm also curious how this is working in my local development without a require anywhere.)
2015-03-28T22:19:52.714077+00:00 app[web.1]: /app/app/models/vote.rb:16:in `<class:Vote>': uninitialized constant Basicstats (NameError)
It sounds like your module isn't being explicitly required or auto-loaded by Rails (this will/won't happen depending which version of Rails you're using and how config.autoload_paths is configured).
Your best bet is to add an initializer which explicitly requires your module:
# config/initializers/basicstats.rb
require Rails.root.join('lib/basicstats')
I'm trying to add my module to my class_eval on Spree.
This is located on: lib/spree/core/app/models/spree/payment/processing.rb
Tried with the following:
module Spree
Payment.class_eval do
require GatewayError
end
end
I am trying to include the following located on: lib/spree/error_override.rb
module Spree
module GatewayError
end
end
The error I'm getting when I try to load the server is:
`block in <module:Spree>': uninitialized constant Spree::GatewayError (NameError)
Its my first time trying to include my own module to a class, would be awesome if someone can point me in the right direction.
Thank you in advance!
One solution would be to manually require the file during initialization process.
config/initializers/require.rb:
# put here all files that you want to require manually
require "#{Rails.root}/lib/spree/error_override.rb"
And that's it - your module is now ready to use ;)
I have a very odd error I cannot wrap my head around.
Basically, I have this class in my lib folder:
# lib/api/amazon.rb
module API
class Amazon
...
end
end
When I want to use it somewhere, I require it:
require 'api/amazon'
API::Amazon.do_stuff
This works initially but after a while it breaks and raises NameError: uninitialized constant API::Amazon. When I debug this and try to require the file again when the error is raised, it returns false, indicating that the file was already loaded. I can also see it in $" (this list of loaded files). Why can I then not access API::Amazon?
Note: I added "API" as an acronym to ActiveSupport::Inflector which is why I don't have to use "Api":
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym 'API'
end
EDIT:
I tried ::API::Amazon.do_stuff as well, same result.
I write some code aimed to get same result as yours, maybe it can give some clue.
trytemp.rb:
module API
class Amazon
def hello
puts "API::Amazon initially works well"
$stdout.flush
end
end
end
s = API::Amazon.new
s.hello
p API.constants
API = Module.new
p API.constants # Here you can see constant Amazon disappers from module API
s = API::Amazon.new
s.hello
It initially works well, then get same error,"uninitialized constant API::Amazon (NameError)":
$ ruby trytemp.rb
API::Amazon initially works well
[:Amazon]
trytemp.rb:15: warning: already initialized constant API
[]
trytemp.rb:19:in `<main>': uninitialized constant API::Amazon (NameError)
EDIT:
I though I had found the answer but the same error just occurred again... :(
END EDIT
It seems that I found the answer, with the help of #uncutstone.
Turns out I had not only used the API namespace for API::Amazon but also for some controllers, like so:
# app/controllers/api/v1/accounts_controller.rb
class API::V1::AccountsController < APIController
...
end
My theory is that one of these controllers was reloaded automatically at some point in time and re-initialized (and therefore cleared out) the API module/namespace.
Thus API::Amazon wasn't available after that, but rerequireing lib/api/amazon.rb didn't help because it had already been required and therefore wasn't loaded again.
I changed the controllers to look like this:
# app/controllers/api/v1/accounts_controller.rb
module API
class V1::AccountsController < APIController
...
end
end
and now it seems to work fine.
I'm working on my first RubyGem voter_love. When I install the Gem and use the up_vote method I get this error:
NameError in MicropostsController#up_vote
uninitialized constant VoterLove::Voter::Vote
Do I need to generate an initializer or require the Gem somewhere in my code to initialize the Votes model?
From here, your model is VoterLove::Votes not VoterLove::Voter::Vote.
And a simple advice: simply adopt a normal Rails app architecture and use the Engine power to have everything painlessly included (models, controllers, views...).
You've most likely referred to a class or module that doesn't exist. Most likely, you've forgotten to require a gem or library needed for the code to work, or you've made a typo. Another possibility is that the class you'd like to refer to is in another module. If that's the case, you'll have to refer to it with its full name as in the following code.
#!/usr/bin/env ruby
module MyModule
class MyClass; end
end
c = MyModule::MyClass.new