Ruby on Rails module require issue - ruby-on-rails

I'm divin to the Rails 3 via some tutorials.
I found usefull the lynda.com/Kevin Skoglund's Rails 3 Essential training.
Close to the end of the course I run into a problem what I can't solve and no reference found on the net (or lynda's site).
There is a position_mover (similar to act_as_list, but simpler) module what I must include to the model's to use.
But I'm getting errors.
This one:
LoadError in SubjectsController#index
no such file to load -- lib/position_mover
Rails.root: C:/Programozas/work/simple_cms
Application Trace | Framework Trace | Full Trace
app/models/subject.rb:1:in `<top (required)>'
app/controllers/subjects_controller.rb:13:in `list'
app/controllers/subjects_controller.rb:8:in `index'
This error occurred while loading the following files:
lib/position_mover
Request
Parameters:
None
Show session dump
Show env dump
Response
Headers:
None
I have access to the example files also. I tried to hard copy the whole app, than modify the gems versions to be correct and I get the same error.
The app runs perfectly untill I try to access a model, where the require presented.
A model:
require 'lib/position_mover'
class Subject < ActiveRecord::Base
include PositionMover
has_many :pages
...
end
I'm sure this is a kind of mega easy thing what I can't recognise. Please help to identify the problem!
Yours,
Kael

What if you remove the lib/ part? If the gem is in your Gemfile it is not even necessary to require it.

Related

undefined method `configure' for MyGem:Module

Context of the Problem
gem 'leanpirates-aarrr', '~> 0.1.1', :path => "/src/gem-aarrr" runs ok
rails g shows the generator lean_pirates:aarrr:install
the initializer is successfully created under config/initializers/leanpirates_aarrr.rb
but the initializer FAILS when trying to configure the gem
The initializer: leanpirates_aarrr.rb
LeanPirates::Aarrr.configure do |config|
config.api_server = "http://localhost:3000"
config.startup_key = Rails.configuration.leanpirates_aarrr.startup_key
config.startup_secret = Rails.application.secrets.leanpirates_startup_secret
end
The gem definition file: aarrr.rb
# (...)
module LeanPirates
module Aarrr
class << self
attr_writer :configuration
end
def self.configuration
#configuration ||= LeanPirates::Aarrr::Domain::Configuration.new
end
def self.reset
#configuration = LeanPirates::Aarrr::Domain::Configuration.new
end
def self.configure
yield(configuration)
end
end
end
The error
/src/app-ebusiness-v3/config/initializers/leanpirates_aarrr.rb:1:in <top (required)>: undefined method 'configure' for LeanPirates::Aarrr:Module (NoMethodError)
/src/app-ebusiness-v3/config/initializers/leanpirates_aarrr.rb:1:in `<top (required)>': undefined method `configure' for LeanPirates::Aarrr:Module (NoMethodError)
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `block in load'
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:259:in `load_dependency'
from /home/ubuntu/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.2/lib/active_support/dependencies.rb:287:in `load'
(...)
This is for the opensource LeanPirates AARRR from https://github.com/lean-pirates/gem-aarrr/tree/simplification (branch simplification)
The Autoloader feature in Rails is very handy, it takes care of a ton of things automagically, but it's also not very smart. If a namespace is already defined it will not load additional files.
It's your obligation as a gem to require any and all support modules or classes that are necessary for your library to work properly.
Here's the problem in lib/gem/aarrr/version.rb:
module LeanPirates
module Aarrr
VERSION = '0.1.1'
end
end
Now LeanPirates::Aarrr is already defined so no additional work by the autoloader is required. As such, your lib/gem/aarrr.rb is never loaded.
To fix this you need to avoid creating that namespace path. You should also ensure that require_paths is set properly in your .gemspec file so that lib/gem is referenced correctly. Right now you'd have to require 'gem/aarrr' which is really confusing and clunky.
I usually set up a plain-old VERSION file in the main gem directory that has nothing but the version string. The gemspec can read this in on-demand if required with File.read, or you can bake it into the .gemspec using a rake task. I prefer the latter approach as making a .gemspec with tons of arbitrary code in it is always over-complicating things.
Problem solved
#tadman guided me in the right direction with his explanation (thanks very much for that), although the problem was bigger than I could initially assess.
The Rails Autoloader was having trouble to load my files. Why? Because I tried to organise them.
The problem was
Namespacing! Long ago, when the gem was started, it felt reasonable to move everything into a /lib/gem folder. However, it proved to be the source of the problem.
With the namespacing not matching the folder structure properly, the Autoloader was having trouble loading the files, and they were not getting recognised along with the classes of my gem, etc.
How was the Namespacing sorted?
When you are doing your gems, make sure that you understand well namespacing. In my case, generating the plugin with the following command line sorted out the problem:
rails plugin new lean_pirates-aarrr
This line above created things in the way they should be for the auto-loader to pick up. It's not something we can complain about: Rails follows a lot the "convention over convention" paradigm.
My end structure was the following:
(https://github.com/lean-pirates/gem-aarrr/tree/simplification)
- lib/
-> generators/
-> lean_pirates/
-> aarrr/
-> install/
-> routines/*.rb
-> templates/*.rb
-> *.rb
-> lean_pirates/
-> aarrr/
-> domain/*.rb
-> helpers/*.rb
-> *.rb
I'd be happier to make /generators and /gem at the root, and I'm sure it would be possible, but I don't really wanna fight the convention, so I'm pretty happy to leave it as is, at least for now.
If you are facing the same problem, fixing the folder structure might help the Autoloader to find your files. Change it, or configure it accordingly.

Ruby on Rails: Using Modules

I am relatively new to Ruby on Rails, but I have almost completed the online course on Lynda. I am stuck on 14-5 "Using the positionMove module". The tutorial is in Rails 3 while my version is Rails 4. I have the solution code, however it does not work for me. I have put my file position_mover.rb in the lib directory. Then in my subject model I require and include the module like this:
require 'lib/position_mover'
class Subject < ActiveRecord::Base
include PositionMover
...
end
I used the methods in this model in the Subject controller just like the instructor. However, when I go to run my app on the Subjects index page I get the error:
cannot load such file -- lib/position_mover
app/models/page.rb:1:in `<top (required)>'
app/views/subjects/list.html.erb:23:in `block in_app_views_subjects_list_html_erb__420960863_60005508'
app/views/subjects/list.html.erb:18:in `_app_views_subjects_list_html_erb__420960863_60005508'
app/controllers/subjects_controller.rb:9:in `index'
I have tried many different approaches that I found online such as adding it to the class definition (Ruby on Rails 4.0 - Loading and using a module) or moving it to a different directory and specifying the path. How do I achieve the same result in Rails 4? What am I doing wrong? Any help is greatly appreciated.
require "#{Rails.root}/lib/position_mover"
or
require_relative 'lib/position_mover'
You also can auto-loading lib files.
in config/application.rb:
config.autoload_paths << Rails.root.join('lib')

Rails: You cannot have more than one Rails::Application (RuntimeError)

I installed a pesapal gem with an initializer file that looks like this;
# Load Pesapal config file when applicatin is loaded ... the config can then be
# accessed from PesapalRails::Application.config.yaml
module PesapalRails
class Application < Rails::Application
config.yaml = YAML::load(IO.read("#{Rails.root}/config/pesapal.yml"))
end
end
When i use it i get the error like this;
/usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.13/lib/rails/application.rb:63:in ``inherited'``: You cannot have more than one Rails::Application (RuntimeError)
With a partial trace looking like this;
from /var/www/html/webapp/config/initializers/pesapal.rb:4:in `<module:PesapalRails>'
from /var/www/html/webapp/config/initializers/pesapal.rb:3:in `<top (required)>'
Fix
Upgrade the gem, v1.2.1 should fix the problem (changelog)
Short Explanation
Simple version ... my approach was wrong - sincere apologies. New to Ruby. New to Rails.
Long Explanation
The initializer was meant to create a global variable that you could access in your rails app. In my case it was PesapalRails::Application.config.yaml. I'd assume in your case, it was different.
The gem assumed that that global variable was set, correctly, which would bring an error since in your app PesapalRails doesn't exist (as you would know, the initializer is ran only when the app is started so this was kinda a safe assumption). This went undetected in my case since my demo app was actually using the PesapalRails namespace.
Request
Wish you would have filed an issue on Github - here next time (it's sheer luck I stumbled on this) ... this way other devs might actually contribute to the discussion/solution. I'm willing to review and push up updates asap.

Why does Rails 4 say Missing Helper file, though it is there?

I wrote a project in Rails 3. There are three controllers, three views, three helper files (very small project).
One of the helper files, which probably is causing the problem:
> cat helpers/my_helper.rb
module MyHelper
require 'some_gems'
...
def my_function ()
... #some functionality
end
end
Now I moved to Rails 4 (updated all the staff).
Still when just starting the app rails s -b localhost -p 3000 and going to localhost:3000 in browser I get an Exception:
AbstractController::Helpers::ClassMethods::MissingHelperError in WelcomeController#index
Missing helper file helpers/my_helper.rb
What is the problem? The file is there, why Rails still missing it?
It could be that the helper could not be loaded because of missing gems from which it is trying to require libraries. Please check that your Gemfile includes all gems that you need for this helper.

How to fix / debug 'expected x.rb to define X.rb' in Rails

I have seen this problem arise in many different circumstances and would like to get the best practices for fixing / debugging it on StackOverflow.
To use a real world example this occurred to me this morning:
expected announcement.rb to define Announcement
The class worked fine in development, testing and from a production console, but failed from in a production Mongrel. Here's the class:
class Announcement < ActiveRecord::Base
has_attachment :content_type => 'audio/mp3', :storage => :s3
end
The issue I would like addressed in the answers is not so much solving this specific problem, but how to properly debug to get Rails to give you a meaningful error as expected x.rb to define X.rb' is often a red herring...
Edit (3 great responses so far, each w/ a partial solution)
Debugging:
From Joe Van Dyk: Try accessing the model via a console on the environment / instance that is causing the error (in the case above: script/console production then type in 'Announcement'.
From Otto: Try setting a minimal plugin set via an initializer, eg: config.plugins = [ :exception_notification, :ssl_requirement, :all ] then re-enable one at a time.
Specific causes:
From Ian Terrell: if you're using attachment_fu make sure you have the correct image processor installed. attachment_fu will require it even if you aren't attaching an image.
From Otto: make sure you didn't name a model that conflicts with a built-in Rails class, eg: Request.
From Josh Lewis: make sure you don't have duplicated class or module names somewhere in your application (or Gem list).
That is a tricky one.
What generally works for me is to run "script/console production" on the production server, and type in:
Announcement
That will usually give you a better error message. But you said you already tried that?
I just ran into this error as well.
The short of it was that my rb file in my lib folder was not in a folder structure to match my module naming convention. This caused the ActiveSupport auto loader to use the wrong module to see if my class constant was defined.
Specifically I had defined the following class
module Foo
class Bar
end
end
In the root of /lib/bar.rb
This caused the autoloader to ask module Object if Bar was defined instead of module Foo.
Moving my rb file to /lib/foo/bar.rb fixed this problem.
I've encountered this before, and the AttachmentFu plugin was to blame. I believe in my case it was due to AttachmentFu expecting a different image processor than what was available, or non-supported versions were also installed. The problem was solved when I explicitly added :with => :rmagick (or similar -- I was using RMagick) to the has_attachment method call even for non-image attachments. Obviously, make sure that your production environment has all the right gems (or freeze them into your application) and supporting software (ImageMagick) installed. YMMV.
As for not getting Rails and AttachmentFu to suck up and hide the real error -- we fixed it before figuring it out completely.
Since this is still the top Google result, I thought I'd share what fixed the problem for me:
I had a module in the lib folder with the exact same name as my application. So, I had a conflict in module names, but I also had a conflict of folder names (not sure if the latter actually makes a difference though).
So, for the OP, make sure you don't have duplicated class or module names somewhere in your application (or Gem list).
For me, the cause was a circular dependency in my class definitions, and the problem only showed up using autotest in Rails. In my case, I didn't need the circular dependency, so I simply removed it.
You can try disabling all your plugins and add them back in one by one.
In environment.rb in the Initalizer section, add a line like this one:
config.plugins = [ :exception_notification, :ssl_requirement, :all ]
Start with the minimum set to run your application and add them in one by one. I usually get this error when I've defined a model that happens to map to an existing filename. For example, a Request model but Rails already has a request.rb that gets loaded first.
I had this problem for a while and in my case the error was always preceded from this S3 error:
(AWS::S3::Operation Aborted) "A
conflicting conditional operation is
currently in progress against this
resource. Please try again."
This problem usually occurs when creating the same bucket over and over again. (Source AWS Developers forum)
This was due to the fact that I had used attachment_fu to create the bucket and I had decommented the line containing the command Bucket.create(##bucket_name) in lib/technoweenie/attachment_fu/backends/s3_backends.rb (near to line 152).
Once commented or deleted the command Bucket.create(##bucket_name) the problem disappeared.
I hope this helps.
Changing class names while using STI caused this for me:
Class changed from 'EDBeneficiary' to 'EdBeneficiary'
Existing records had 'EDBeneficiary' stored in the 'type' column, so when Rails tried to load them up the exception was raised.
Fix: Run a migration to update values in the 'type' column to match the new class name.
in my case, I am getting this error in the development console but I can load the class in irb
Sorry this isn't a definitive answer, but another approach that might work in some specific circumstance:
I just ran in to this problem while debugging a site using Ruby 1.8.7 and Merb 1.0.15. It seemed that the class in question (let's call it SomeClass) was falling out of scope, but when some_class.rb file was automatically loaded, the other files it required (some_class/base.rb etc) were not loaded by the require mechanism. Possibly a bug in require?
If I required some_class file earlier, such as the end of environment.rb, it seems to prevent the object falling out of scope.
I was getting this error duo to a controller definition being in a file that wasn't named as a controller. For instance, you have a Comment model and you define the controller in a comment.rb file instead of comments_controller.rb
I had this problem with rails version 1.2.3. I could reproduce the problem only with mongrel, using console environment access didn't give any useful info. In my case, I solved making the RAILS_ROOT/html folder writable by mongrel and then restarting the web server, as some users reported here:
http://www.ruby-forum.com/topic/77708
When I upgraded rails from 1.1.6 to 1.2.6 and 2.0.5 for my app, I faced this error. In short, old plugins caused this error. These plugins were already out-dated and no update anymore (even no repo!). After I removed them, the app worked on 1.2.6 and 2.0.5. But I didn't check the detail source code of the plugins.

Resources