I'd like to include TestModule in MyModule:
# in test_module.rb
module TestModule
SOMETHING = [1, 2, 3]
end
# in my_module.rb
module MyModule
include TestModule
def my_method
"testing"
end
end
I'm receiving this error:
Routing Error: uninitialized constant MyModule::TestModule
I've double-checked the rails naming convention. Any idea why this isn't working?
More info: config.autoload_paths += ... in application.rb is commented out. However other modules in /lib are being loaded somehow.
More info 2: I think rails can't see the new file test_module.rb. If I add a new module to an existing file containing a module then including the new module works. Is there some sort of rails clean-up or refresh process for the $LOAD_PATH or something?
You can also try with this:
# in my_module.rb
load 'test_module.rb'
module MyModule
include ::TestModule
def my_method
"testing"
end
end
to refer to top-level namespace.
Try adding a "require" to the top of the file like this:
# in my_module.rb
require 'test_module'
module MyModule
include TestModule
...
Related
I have some code i've inherited and am in the process of upgrading it to Rails 3.1. I'm suuuuper close to done but I got a bug.
In Rails Console I run User.first and I get this error
undefined local variable or method `acts_as_userstamp' for #<Class:0x000000046bef50>
Now acts_as_userstamp is a method located on line two inside my User model
class User < ActiveRecord::Base
#TODO /lib is not loading??? or is it??? why this method not work in browser?
acts_as_userstamp
And is defined in a file called app/lib/model_modifications.rb.
Now I recently discovered that my app/lib folder was not being autoloaded in my application.rb file and I think that's been fixed...or has it? Is this file correct? Or no?
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# evil outdated soap middleware, TODO: kill it with fire
# Does this have to be loaded BEFORE the first line???
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', "vendor", "soap4r"))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', "vendor", "plugins", "soap4r-middleware", "lib"))
# evil outdated soap middleware, TODO: kill it with fire
require 'soap4r-middleware'
require File.join(File.dirname(__FILE__), '..', 'app', 'lib', 'soap.rb')
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 MyappDev
class Application < Rails::Application
# startup the lib directory goodies <-- IS THIS CORRECT???
# config.autoload_paths << "#{Rails.root}/lib"
# config.autoload_paths += %W( lib/ )
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
# 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]
config.middleware.use MyAPIMiddleware
end
end
I'm trying to debug this file as I post this now. Here is a peak at it's internal structure...(i've just included the overall structure for the sake of brevity)
app/lib/model_modificatons.rb
class Bignum
...
end
class Fixnum
...
end
class ProcessorDaemon
...
end
module ActiveRecord
module UserMonitor
...
end
module MyLogger
...
end
end
class Object
...
end
class Struct
...
end
class String
...
end
class Fixnum
...
end
class OpenStruct
...
end
class ActiveRecord::Base
def self.visible_columns
...
end
...
def self.acts_as_userstamp
logger.info "HI fonso - acts_as_userstamp is called"
include ActiveRecord::UserMonitor
end
...
protected
def self.range_math(*ranges)
...
end
end
class Array
...
end
class DB
...
end
If you can spot a problem with the overall structure or anywhere else please let me know.
So why is this method not found? I'm trying to debug it as I'm posting this and I'm getting nothing.
I suspect the file app/lib/model_modifications.rb is not being loading. That nothing in the /lib directory is being loaded..but how do I confirm this?
Thank you for reading this far, I hope I've not rambled on too much.
autoload_path configuration does not load all the given files on the boot but defines folders where rails will be searching for defined constants.
When your application is loaded, most of the constants in your application are not there. Rails have a "clever" way of delaying loading the files by using a constant_missing method on Module. Basically, when Ruby encounters a constant in the code and fails to resolve it, it executes said method. THe sntandard implementation of this method is to raise UndefinedConstant exception, but rails overrides it to search all of its autoload_paths for a file with a name matching the missing constant, require it and then check again if the missing constant is now present.
So, in your code everything works as expected and you need to load this extension file manually. If you want to have some code that executes on the application boot, put your file within config/initializers folder.
Aside: Try avoiding monkey patching whenever possible. It might be looking clever, but adding more methods to already overpopulated classes will not make them easier to use.
I am attempting to create a permissions structure for users in my application. I created a permissions.rb file in the lib/ directory in my rails application.
When I try to include Permissions in my user model I am getting this error.
This is what I have in the user model.
class User < ApplicationRecord
include Permissions
...
end
How can I include this file and its methods without getting this error?
To include modules under lib folder you will need to add your lib folder in autoload_path in your application.rb
config.autoload_paths += %W( #{config.root}/lib/)
add this line in your application.rb.
I think it would be good if you use autoload file when application start then it would like to on the application.rb
config.autoload_paths << Rails.root.join('lib')
Or you can use user.rb
class User < ApplicationRecord
load File.join(Rails.root, 'lib', 'permissions.rb')
end
The module would look like this, always make sure the naming conventions is right like if run module name on the console with underscore then he would give your file name, see the below if your module name is Permissions then
Loading development environment (Rails 5.1.4)
2.3.4 :001 > "Permissions".underscore
=> "permissions"
your file name is permissions.rb
#=> permissions.rb
module Permissions
...
def self.method #=> method name instead of the method
#=> code staff here
end
or
def method #=> method name instead of the method
#=> code staff here
end
...
end
Hope it helps
Recently, I can't make changes to my app without restarting my development server, otherwise I receive this error:
LoadError (Unable to autoload constant BotFeedback, expected ../../bot_feedback.rb to define it)
This hasn't been a problem before and I'm not entirely sure why this has become a problem. I have these settings configured in application.rb:
# Auto-load the bot and its subdirectories
config.paths.add File.join('app', 'bot'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'bot', '*')]
My app/bot folder includes files such as:
bot.rb with:
require "#{Rails.root}/app/bot/orderbot.rb"
Bot.on :message do |message|
OrderBot.new()
..
end
def somefunction
OrderBot.new()
..
end
orderbot.rb with:
require "#{Rails.root}/app/bot/bot_feedback.rb"
require "#{Rails.root}/app/bot/bot_demo.rb"
require "#{Rails.root}/app/bot/bot_helper.rb"
class OrderBot
include BotFeedback
include BotDemo
include BotHelper
(many more includes)
..
end
bot_feedback.rb with:
require "#{Rails.root}/app/models/concerns/sharedmethods.rb"
class OrderBot
include Sharedmethods
module BotFeedback
...
end
end
bot_demo.rb with:
class OrderBot
module BotDemo
..
end
end
bot_helper.rb with:
require "#{Rails.root}/app/models/concerns/sharedmethods.rb"
class OrderBot
include Sharedmethods
module BotHelper
...
end
end
My guess is that including the sharedmethods file is causing this because I don't see anything else being a problem. Changing the sharedmethods file in the rails app has always seemed to require restarting the server.
I would appreciate any help/suggestions.
UPDATE:
Looks like using 'load' instead of 'require' seems to solve the problem. I'm not sure this is the right way to go about it though.. because it will take up more memory if the files are being loaded again and again?
load "#{Rails.root}/app/bot/bot_feedback.rb"
load "#{Rails.root}/app/bot/bot_demo.rb"
load "#{Rails.root}/app/bot/bot_helper.rb"
Finally figured out the answer after learning everything about rails 'autoload' and 'require'
I don't actually need to 'require' any of the files because they are already autoloaded. The culprit was the 'module', it wasn't necessary.
I'm trying to simplify our configuration by creating small configuration classes that can be included in our application.rb.
lib/logging.rb
class << Logging
def configure(config)
# ... configure logging stuff
end
end
application.rb
require 'lib'
module MyApp
class Application < Rails::Application
Logging.configure(config)
end
end
The problem is if I don't use require "lib" then I get an Undefined Constant Logging error. But if I try to require it I get:
bin/rails:6: warning: already initialized constant APP_PATH
/opt/qtip/bin/rails:6: warning: previous definition of APP_PATH was here
The only way I've been able to get it to work is by doing this which is very limiting.
config.autoload_paths = %w(lib)
config.after_initialize do
::Logging.configure(config)
end
You have wrong class declaration.
Instead
class << Logging
you should use
class Logging
class << self
def configure(config)
end
end
end
Adding lib to config autoload paths does not autoload my module in Rails 3.
I add in my config/application.rb file.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
In my controller I added
require 'lib_util' (or)
include LibUtil #both doesn't work
In my lib/lib_util.rb file, I have the following module
module LibUtil
module ClassMethods
def p_key(a,b)
//mycode
end
end
def self.included(receiver)
receiver.extend ClassMethods
end
end
I get the error undefined method `p_key'. The important thing to be noted is I ve called the same module in my model it works fine. But in my controller it does not identify the module.
Can anybody guide me??
Did you try including both the modules ?
include LibUtil::ClassMethods