I was able recently to organize my code by grouping everything into folders.
I had an issue with having the same "group name" for both my group of controllers under the app/ directory and my module under the lib/ directory but I was able to fix by following this:
Rails: Same name for a library module and a group of controllers?
I also know that whenever you change your lib code, you need to restart the rails server which is totally fine by me.
But after the recent re-organization, every time I change the code in the controllers, I get the following error!!!
NameError at /admin
uninitialized constant Admin::PagerDuty
and to resolve it, I simply restart the server!!
Any advice?!
EDIT: STRUCTURE:
Controller main_controller.rb is under app/controllers/admin
class Admin::MainController < ApplicationController
end
Helper main_helper.rb is under app/helpers/admin
module Admin::MainHelper
require "admin/pager_duty.rb"
def pager_duty
pagerduty = Admin::PagerDuty.new()
#on_call = pagerduty.on_call()
#counts = pagerduty.open_incidents()
end
end
lib pager_duty.rb is under lib/admin
module Admin
class PagerDuty
....
end
end
Try changing
require "admin/pager_duty.rb"
to
require_dependency "admin/pager_duty.rb"
in your module.
Related
in Rails 5.0.1 application I have file app/actions/frontend/cart/get_cart_items_summarized.rb with:
module Actions
module Frontend
module Cart
class GetCartItemsSummarized
#content here
end
end
end
end
And in app/helpers/application_helper.rb I call it:
def get_cart_items
#...
items = Actions::Frontend::Cart::GetCartItemsSummarized.new.call
#...
end
But I'm getting:
uninitialized constant ApplicationHelper::Actions
Why? How should I use this class?
Thanks
In rails/autoloading, the first level of directories, the one directly under app, is not considered a part of the name. It is so that your model can be just User and not Models::User, etc.
My solution to this is to put all custom stuff in app/lib. This way, lib eats that non-naming layer and the rest of your folder structure become a name. In your example, put your file to
app/lib/actions/frontend/cart/get_cart_items_summarized.rb
Of course, feel free to replace "lib" with whatever you want ("app/custom", for example). This name doesn't matter.
Either use a full-qualified name:
::Actions::Frontend::Cart::GetCartItemsSummarized.new.call
or just stick to Rails constant lookup (the below should work):
GetCartItemsSummarized.new.call
In "config/application.rb", add "app" to autoload paths, e.g.:
class Application < Rails::Application
config.autoload_paths += Dir[Rails.root.join('app')]
end
So the core issue at heart here is the following message:
`<class:ApplicationController>': uninitialized constant Xaaron::Core (NameError)
So I think some of the steps I have done will be redundant, but I am new to trying to add code to my library folder in a rails engine, in rails its rather easy. But here its not so much.
So here is what I have done:
in:
xaaron/
lib/
xaaron/
I have a directory called core/ with a file called loder.rb.
Inside of core is a directory called controllers and in side there is a file called user_controller which looks like:
module Xaaron
module Core
module UserController
def assign_to_member_group(user)
memeber = Xaron::Group.find('member')
user.add_group = memeber.group_name
end
end
end
end
To load this I have a loader file:
module Xaaron
module Core
module Loader
include Xaaron::Core::Controllers::UserController
end
end
end
Which I do not think is needed because in the engine.rb file I do: config.autoload_paths << File.expand_path("../xaaron/core/**", __FILE__) which just goes up one directory to the lib/ directory and loads xaaron/core/ and everything in it (or so I thought).
This loader.rb file is included in the ApplicationController
module Xaaron
class ApplicationController < ActionController::Base
...
include Xaaron::Core::Loader
...
end
end
So:
Whats the proper way to load my "core" library
Why am I getting the error above?
I guess your problem is with config.autoload_paths << File.expand_path("../xaaron/core/**", __FILE__). It expands into smth like Rails.root/lib/engine_name/xaaron/core/** and your lib path should be Rails.root/lib/xaaron/core. So, in your case, lib path should be config.autoload_paths << File.expand_path("../../xaaron/core", __FILE__)
Moreover, beeing within your ApplicationController, it is enough to include include Core::Loader, because you're already within Xaaron namespace.
Before you'll start working with controllers, try just call your module Xaaron::Core::Loader within rails console.
I have the following in my controller:
class SurveysController < ApplicationController
def index
survey_provider = FluidSurveysProviders::SurveyProvider.new
contact_lists = survey_provider.get_lists()
#survey = Survey.new(contact_lists)
end
And I'm receiving this error:
NameError in SurveysController#index
uninitialized constant SurveysController::FluidSurveysProviders
Excuse my Rails noobiness, I'm sure I'm leaving out something important here. But it seems to me that I am trying to "initialize" the constant with this line:
survey_provider = FluidSurveysProviders::SurveyProvider.new
But that's the same line that's throwing an error because it's not initialized. Where should I be "initializing" the Provider?
Once you require fluid_surveys_providers (or similar) then do this:
include FluidSurveysProviders
Make sure SurveyProvider is wrapped with module FluidSurveysProviders. It may look like this
module FluidSurveysProviders
class SurveyProvider
...
end
end
if its an ActiveRecord object try this
class FluidSurveysProviders::SurveyProvider < ActiveRecord::Base
...
end
The SurveyProvider was not loaded correctly.
For a quick fix, move the class file into app directory, e.g. app/lib/survey_provider.rb. Then all code inside app will be auto-loaded by Rails.
Or make sure the path to class SurveyProvider is included in the autoload_path of Rails. In config/application.rb
config.autoload_paths += %W(#{config.root}/lib) # where lib is directory to survery_provider
If you use Rails 5, be careful that autoload is disabled in production environment. Check this link for more info.
I'm trying to extract a portion of my Rails project into my lib directory but I can't work out how to link my files up correctly. My directory structure looks like this:
lib/
eventable/
calendar.rb
helpers.rb
# Rest of rails directories/files
I'm requiring the eventable directory in config/application.rb:
config.autoload_paths += %W(#{config.root}/lib #{config.root}/lib/eventable)
My helpers and calendar rb files:
# helpers.rb
module Eventable
module Helpers
def calendar_for...
Calendar.new...
end
end
end
# calendar.rb
module Eventable
class Calendar
# methods defined here
end
end
I'm then mixing my Eventable::Helpers module in the regular Rails helpers so that I can use calendar_for in my views:
ActionView::Base.send :include, Eventable::Helpers
This last step seems to work fine. However, when I go to a view which is using this helper I get:
uninitialized constant Eventable::Helpers::Calendar
If I change my helper so that it tries to access Eventable::Calendar.new instead then I get:
uninitialized constant Eventable::Calendar
When I had all of these in a single file, it all worked perfectly. So how I can correctly link these files up?
It looks like you need a loader-type file to tell Rails where to find code for the Eventable module.
Try add a lib/eventable.rb with:
module Eventable
autoload :Calendar, 'eventable/calendar'
autoload :Helpers, 'eventable/helpers'
end
You shouldn't need to change your load path if you have the loader file in place.
I had a similar problem. I solved it by changing the way modules are required.
In application.rb
config.autoload_paths += Dir["#{config.root}/lib/"]
Create /lib/eventable.rb with the following code
require "eventable/helpers"
require "eventable/calendar"
I'm developing a web application in Rails 2.3.5.
I defined the module in lib/ folder as follows.
module TestModule
class Basic < ApplicationController
def show
p "module method"
end
end
end
and the load_paths are described in the environment.rb for this library as follows
Rails::Initializer.run do |config|
config.load_paths += %W[ #{RAILS_ROOT}/lib/test_module ]
end
but temporally, I want to override the above method without editing the lib method.
So, I put the override method in the "config/initializers/override_show.rb" as follows.
require_dependency "lib/test_module/basic.rb"
module TestModule
class Basic
def show
p "new method"
end
end
end
without "require_dependency", I get an error, because the original method located in lib/ folder wasn't loaded, so I put the "require_dependency" before overriding the TestModule.
In the above code, the new method works fine only once just after activating the server.
However, the new method is never called again, and the old method is called.
When I restart the rails server, the new method will be called just once.
Please give me some advice on how to override the method in the lib folder.
Thank you very much in advance.
Is it possible that you simply append the code in config/initializers/override_show.rb to lib/test_module/basic.rb ?