Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails /lib modules and

I am writing a custom wrapper for open_flash_chart plugin. It's placed in /lib and load it as a module in ApplicationController.

However, I have some Class hierarchy or smth problem.

From any controller I can access open_flash_chart functions as OpenFlashChart, Line etc

However, in a class in a /lib module, it doesnt work!

Any ideas?

like image 356
Mantas Avatar asked Jul 02 '09 08:07

Mantas


People also ask

What are modules in Rails?

Modules provide a structure to collect Ruby classes, methods, and constants into a single, separately named and defined unit. This is useful so you can avoid clashes with existing classes, methods, and constants, and also so that you can add (mix in) the functionality of modules into your classes.

What is the lib directory for in Rails?

In Rails's directory structure as far back as I can recall, there's always been a lib folder. This folder is for files that don't belong in the app folder (not controllers, helpers, mailers, models, observers or views), such as modules that are included into other areas of the application.

What are Mixins in Rails?

Mixins provides a controlled way of adding functionality to classes. The code in the mixin starts to interact with code in the class. In Ruby, a code wrapped up in a module is called mixins that a class can include or extend. A class consist many mixins.

Where do you put modules in Rails?

The more nuanced answer. The truth is that you can put your modules anywhere. Personally, my main use for modules is to create namespaces for my Active Record models to help keep things organized. Those module definitions just end up in the same files as my Active Record models.


1 Answers

There are two ways that files get loaded in Rails:

  • It is registered in the autoload process, and you reference a constant that corresponds to the file name. For instance, if you have app/controllers/pages_controller.rb and reference PagesController, app/controllers/pages_controller.rb will automatically be loaded. This happens for a preset list of directories in the load path. This is a feature of Rails, and is not part of the normal Ruby load process.
  • Files are explicitly required. If a file is required, Ruby looks through the entire list of paths in your load paths, and find the first case where the file you required is in the load path. You can see the entire load path by inspecting $LOAD_PATH (an alias for $:).

Since lib is in your load path, you have two options: either name your files with the same names as the constants, so Rails will automatically pick them up when you reference the constant in question, or explicitly require the module.

I also notice that you might be confused about another thing. ApplicationController is not the root object in the system. Observe:

module MyModule   def im_awesome     puts "#{self} is so awesome"   end end  class ApplicationController < ActionController::Base   include MyModule end  class AnotherClass end  AnotherClass.new.im_awesome # NoMethodError: undefined method `im_awesome' for #<AnotherClass:0x101208ad0> 

You will need to include the module into whatever class you want to use it in.

class AnotherClass   include MyModule end  AnotherClass.new.im_awesome # AnotherClass is so awesome 

Of course, in order to be able to include the module in the first place, you'll need to have it available (using either of the techniques above).

like image 92
Yehuda Katz Avatar answered Sep 26 '22 23:09

Yehuda Katz