under lib/ I have 'aisis_writer/loader.rb' which, inside that file, looks like:
module AisisWriter
module Loader
end
end
I then have, in my application.rb the following set up:
require File.expand_path('../boot', __FILE__)
# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env)
module AisisWriter
class Application < Rails::Application
# Load Lib
config.autoload_paths += %W(#{config.root}/lib)
# Use Rack Attack For Throttling
config.middleware.use Rack::Attack
end
end
From there I did, in the ApplicationController.rb: include AisisWriter::Loader and then I ran my tests and got:
'<class:ApplicationController>': uninitialized constant AisisWriter::Loader (NameError)
Either I cannot do what I am doing because of naming conflicts or I am doing something wrong. Any one care to tell me what I might be doing wrong?
I don't think your config.autoload_paths is broad enough -- it's not including subfiles of the lib directory.
This should do the trick:
config.autoload_paths += Dir[Rails.root.join('lib', '{**/}')]
Try defining like this within 'aisis_writer/loader.rb'
module AisisWriter::Loader
end
Related
I have a class in libs and try to use it in a controller. However I cannot access it. I tried to use the autoload function, but that doesn't work, and it shouldn't work in rails 5 in production mode, so I guess I don't need to try this one.. I also tried to require it in my controller, but I don't get the syntax correct I guess. I'm also wondering where to put my class, since I have read several different opinions..
config/application.rb
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 Qipmatedevel
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1
config.active_job.queue_adapter = :sidekiq
config.autoload_paths += %W(#{config.root}/lib)
# 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.
end
end
app/controller/imports_controller
class ImportsController < ApplicationController
require 'lib/class_qip'
adding
require './lib/class_qip.rb'
fixed it
Put your classes in lib directory only & load as,
config.eager_load_paths << Rails.root.join('lib')
It works on both development and production environment.
I'm trying to use a module from the folder 'app/helpers/transaction_helper.rb'. (It's important to note that the application is using the api_only flag, and helpers aren't being generated or loaded by default.)
module TransactionHelper
module Generator
def self.code_alphanumeric(params)
end
end
end
I got this error:
NameError: uninitialized constant TransactionHelper
I tried to add the following line to the application.rb
config.autoload_paths += %W(#{config.root}/app/helpers)
require_relative 'boot'
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
# require "sprockets/railtie"
require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module SistemaControleContasApi
class Application < Rails::Application
config.autoload_paths += %W(#{config.root}/app/helpers)
# 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.
# Only loads a smaller set of middleware suitable for API only apps.
# Middleware like session, flash, cookies can be added back manually.
# Skip views, helpers and assets when generating a new resource.
config.api_only = true
end
end
But this until not work. If I try to put this file in the app/models directory, this work. However, this is not the right local to place a helper.
Could someone help, please?
Normally everything under app is autoloaded by default if you follow the Rails™ naming conventions. See here Docs.
set_autoload_paths: This initializer runs before bootstrap_hook. Adds
all sub-directories of app and paths specified by
config.autoload_paths, config.eager_load_paths and
config.autoload_once_paths to
ActiveSupport::Dependencies.autoload_paths.
So in the first step you should remove config.autoload_paths += %W(#{config.root}/app/helpers) from your config.
Then for every module you should create a subfolder.
So for your problem you should put your module under app/modules/transaction_helper/generator.rb
Also you don't need self in a module scope.
Personally I would create the helper as follows:
module TransactionHelper
def generate_alphanumeric_code
# params are automatically available in helpers.
end
end
And put it under app/modules/transaction_helper.rb.
How do I include a 'lib/' class or module in my models, Grape API and tests? For example, I have a class:
ROOT/lib/links/link.rb
module Links
class Link
...
end
end
And I want to include that class in my User model (app/models/user.rb), User Grape API (app/api/v1/users.rb), and testing suites (test/models/user_test.rb and test/api/v1/users/users_links_test.rb)
For example, I tried accessing it in my tests through
link = Links::Link.new(LINK_NAME, LINK_SITE)
but I get:
uninitialized constant API::V1::Users::APITest::Links
I've tried adding this to my config/application.rb:
config.autoload_paths += Dir["#{Rails.root}/lib/**"]
require_relative 'boot'
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
# require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module ArbitraryAppName
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.
# Auto-load API and its subdirectories
config.paths.add 'app/api', glob: '**/*.rb'
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
config.autoload_paths << "#{Rails.root}/lib"
# For Cross-Origin Resource Sharing (rack-cors)
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options]
end
end
end
end
but it doesn't work. What am I missing? How do I include lib files and how should I be calling those classes?
EDIT:
It seems like the only way I can access it is if I do:
require "#{Rails.root}/lib/links/link"
Is there a better, more conventional way?
There seems to be another issue, adding config.autoload_paths << whatever does not seem to be doing anything. For example, when I puts ActiveSupport::Dependencies.autoload_paths in rails console, my changes do not appear.
No, you shouldn't resort to using require (if you want to follow Rails conventions). Rails autoloading is based on paths and namespacing, as those two things have to match up. Besides the initial problem with namespacing that was fixed, the way you modify the autoload paths is incorrect. It should be done this way:
config.autoload_paths << "#{Rails.root}/lib"
This is if you want to leave lib/ at the root of your project. As mentioned in the comments, you could move it into your app/ directory.
Paul Hoffer's answer is the accepted answer but for anyone who notices that any changes to config/application.rb isn't persisting:
There seems to have been an issue with Spring, where any changes to the config/application.rb file wasn't persisting. I had to run spring stop to get things to work again. If anyone can explain why this happens sometimes, that'd be nice.
You should not put your lib into autoload_paths (as Paul Hoffer suggested), since doing so will prevent it being eager loaded in production (when config.eager_load = true).
You will find extensive guide on this topic here: http://hakunin.com/rails3-load-paths
Every time I call validates_with NumberValidator. I get an uninitialized constant error. I have created a directory called validators under the "app" directory. This is what I have so far.
This is my model
class Worker < ActiveRecord::Base
include ActiveModel::Validations
validates_with NumberValidator
end
This is my validator file
class NumberValidator < ActiveModel::Validator
def validate(record, attribute, value)
puts record
puts attribute
puts value
end
end
require File.expand_path('../boot', __FILE__)
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module ApplicationName
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.
# 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
# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
config.autoload_paths += %W["#{config.root}/app/validators/"]
end
end
I have restarted my server and I'm just not sure what I am doing wrong
Rails will automatically load anything under app/ assuming you follow the expected structure. The way Rails does this is with Constant Autoloading, which maps a constant, such as MyValidator to a file name, such as my_validator.rb under a directory in the autoload paths.
In order for Rails to load your NumberValidator, you should name the file number_validator.rb and put it in a folder in the autoload path, such as app/validators/number_validator.rb. You will need to restart the server if you have added a directory under app because these are initialized at boot time (be sure to run spring stop if you are using spring so it restarts too!).
Notes:
You do not need to add anything under app to your app config, so you can remove the config.autoload_paths line.
ActiveRecord::Base already includes ActiveModel::Validations, so you can also remove that include from your Worker class.
For more information on how this process works, check out the Autoloading and Reloading Constants page in the Rails Guides.
This is just a curious irritant, but why does my app not include the expected line in config/application.rb, or anywhere else?
require 'rails/all'
This app was generated using Rails Composer in early 2014, if that makes a difference. Also, it is Rails 4.2.1.
The issue arose only because I am studying the Configuring Rails Applications and the The Rails Initialization Process guides as I have a need to modify my initialization process. Both state that the config/application.rb file is expected to contain that line, but mine does not. And, yes, the app runs just fine locally and on Heroku, so... Why?
My file is:
require File.expand_path('../boot', __FILE__)
# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env)
module Theappname
class Application < Rails::Application
config.generators do |g|
# Enable Chrome Source Maps so CSS and JS can be debugged
#g.sass_options = { :debug_info => true }
# don't generate RSpec tests for views and helpers
g.test_framework :rspec, fixture: true
g.fixture_replacement :factory_girl, dir: 'spec/factories'
g.view_specs false
g.helper_specs false
end
# Rails 4 should include all helpers for controllers and views
config.action_controller.include_all_helpers = true
# 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.
# 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 = 'Eastern Time (US & Canada)'
config.time_zone = 'UTC' # Don't use local time or you won't notice time issues.
# 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
# Do not check for unavailable locales
I18n.enforce_available_locales = false
# not needed at 4.0
config.assets.initialize_on_precompile = false
# Load files in lib
config.autoload_paths += %W(#{config.root}/lib)
# Extend Rails classes in lib/core_ext/<classname>.rb... See above?
#config.autoload_paths += Dir[File.join(Rails.root, "lib", "core_ext", "*.rb")].each {|l| require l }
# 20150711 Default Date formats
#default_date_formats = { :default => '%d.%m.%Y' }
default_date_formats = { :default => '%Y.%m.%d' }
Time::DATE_FORMATS.merge!(default_date_formats)
Date::DATE_FORMATS.merge!(default_date_formats)
# 20150808 Adding Delayed_Job queueing for daily_report and such
config.active_job.queue_adapter = :delayed_job
end
end
You can require 'rails/all' if that suits your fancy, but the parts of rails necessary to run your application are required with these lines:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "sprockets/railtie"
If I were to guess the motivation for this, it is probably that you don't necessarily need or want all of the parts of rails in your application, so better to explicitly require the ones you want instead of everything. In this case if you were to require 'rails/all' you would end up with action_view, active_job, and rails/test_unit as well as the above. The files required can be found in railties.