Rails autoload module when application started - ruby-on-rails

i have module Mymodule,inside lib directory, within few methods inside
module Mymodule
def usefull_meth(a,b)
a+b
end
end
i want to autoload it when my app started
i have inside my application.rb
config.autoload_paths += Dir["#{config.root}/lib/**/*"]
but i still need to include it like include Mymodule
i want to use my usefull_meth(a,b) inside application helper without inclusion
how i can achieve my goal? or i have done something wrong?
I simply want to have usefull_meth anywhere in my helpers,i do not need Mymodule.usefull_meth or smth else

but i still need to include it like include Mymodule
This is how Ruby works, it has nothing to do with Rails autoload.
In order to use some method globally, you should put it into global namespace. Just remove module definition and leave only method definition in that file(even though I don't understand why don't you put it into helper directly).

I achieved what i wanted
inside application.rb
require './lib/my_module'
include Mymodule
and now i have necessary methods with out include Mymodule

Related

Rails doesn't load my module from lib

I have a bunch of custom classes in my Rails 3.2 app in lib folder: i.e. extending ActiveRecord, etc. It all works fine.
However I'm trying to add a couple of custom methods to FileUtils, i.e.
module FileUtils
def last_modified_file(path='.')
# blah ...
end
end
I put it in lib/file_utils.rb
In my application.rb I have
config.autoload_paths += %W(#{config.root}/lib)
My other custom classed are loaded but not the module.
I read (Best way to load module/class from lib folder in Rails 3? ) that I'm supposed to define a class inside module in order for Rails to pick it up and according to FileUtils.class - it should be Object < BasicObject.
So I tried
module FileUtils
class Object
def last_modified_file(path='.')
# blah ...
end
end
end
But that doesn't work either.
However when I fire up irb and just paste my code which effectivly puts my new code inside object and reinclude my module - it works fine.
Whaat amd I missing here?
Your patch is never going to be loaded because autoload is only invoked when Rails can't find a constant. Since the FileUtils constant already exists, the autoloader is never called, and your file is never loaded.
Simply require it from an initializer.
require File.join(Rails.root, "lib/file_utils.rb")

Autoload function from lib folder

I have added options in application.rb:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
and lib\functions.rb:
def some_lib
return "#######################################"
end
In controller I'm trying to call this function, but get the error:
undefined local variable or method `some_lib' for #<TodosController:0x49a3850>
How can I fix it?
In order to have rails autoload from the lib dir, you need to follow rails naming conventions.
lib/functions.rb
class Functions
def self.some_lib
return "#######################################"
end
end
Then you can Functions.some_lib
Or
lib/functions.rb
module Functions
def some_lib
return "#######################################"
end
end
Then include Functions where you need your methods. This allows you to execute:
some_lib
Yeah, basically, don't do that, ruby is an OO language, you're trying to make a procedural language.
There's some way to make it do exactly what you ask involving mixing new methods into Kernel or Object... but that's really not what you want to do.
Do you want to add that new method to all controllers, and not neccesarily to other places? Then just add it to your ApplicationController (./app/controllers/application_controller.rb). Or add it to a module in ./lib, and then "include MyControllerFunctions" into ApplicationController.
Do you really want to be able to use it anywhere at all? Then I'd do what Kyle suggests, make it a module method, and call it as MyFunctions.some_method.
Ruby will let you do just about anything, you could manage to make it callable the way you want from any class at all... but really, you don't want to, it's just gonna lead to a mess.

How do I invoke a method from a custom module?

I've created a module in the /lib folder:
Module CookieHelper
$str = cookies["shoppingcart"]
def get_all_cookie_info()
end
end
But this isn't working. If I move the code into a controller it works fine.
Also, I'm trying to invoke the method within this module. I've tried:
require CookieHelper
CookieHelper::get_all_cookie_info()
to use methods from a module inside of an other class (such as a controller), you do something like this:
include CookieHelper
Once you do that inside of your controller's class, you can call get_all_cookie_info() with just the method name.
It sounds like you might be trying to something odd, so if you want to spell out what get_all_cookie_info is supposed to do, then maybe I can offer more advice.
CookieHelper::get_all_cookie_info is the correct way to call this method.
include CookieHelper
get_all_cookie_info
is another valid way, if you want include all of the methods in cookie helper available without having to namespace them (once the file lib/cookie_helper has been loaded).
What the issue probably is, is that the lib file isn't even required yet, this is because rails3 doesn't automatically load files in lib anymore. You can tell it to do so by editing your application.rb file, and setting inside class Application < Rails::Application
config.autoload_paths += %W( #{config.root}/lib )

Where is the best place to extend the functionality of built in classes in Rails?

I have a few methods I am adding to Ruby's Array class for my Rails application. Where is the best place to put them?
Right now I have them in config/environment.rb.
config/environment.rb isn't really the best place, since you can run into serious load ordering-problems if try to extend classes that haven't been resolved at the time environment.rb is executed.
Better to put a file into config/initializers. Any script placed there will be executed after the rails runtime is loaded.
What you could do is to create a file lib/my_extensions.rb
module MyExtensions
end
then in lib/my_extensions/array.rb :
module MyExtensions::Array
def join_with_commas
join(", ")
end
end
and in config/initializers/load_my_extensions.rb
class Array
include MyExtensions::Array
end
This will cause MyExtensions::Array to be auto-reloaded each time you invoke a request in development mode. This is nicer than restarting your application everytime you make a change to your code.
It would probably be cleaner to add a lib/ directory with all your extensions. Then add a line in config/environment.rb that loads the file:
require File.join(RAILS_ROOT, 'lib', 'array.rb')

Overriding ApplicationHelper?

There is an ApplicationHelper in an engine we're using that looks like this:
module ApplicationHelper
def page_title()
# ...
end
end
This gets called by a number of views in the engine. I'd like to override this method in my application to provide a different default title. How do I do this? Simply defining my own ApplicationHelper didn't seem to work.
Did you define the page_title method in your ApplicationHelper module? Just having an ApplicationHelper by itself won't do it.
By default, your ApplicationHelper module should already be in app/helpers/application_helper.rb. Your app files are required by rails after it requires the plugins you are using. That means any method you define in app/helpers/application_helper.rb should override methods defined in the plugins code.
This behavior arises out of ruby's open class structure. Any time, anywhere any class/module/object can be reopened to add methods and attributes to it. More or less.
Could you post some of the code you are trying to override the engine method with?
Are other methods defined in your ApplicationHelper available?
If yes, the engine helper is probably loaded before your ApplicationHelper, and your method overwritten.
If no, Rails may never have loaded your module because it thinks it already knows about ApplicationHelper and doesn't try to load it again.

Resources