Using class function from the lib directory in rails - ruby-on-rails

I am creating a rails3 application and I want to create a class that handles string formatting, so I made a class called FormatUtilites.rb in the lib directory but whenever I try calling it from somewhere else in my app I get this error:
ActionView::Template::Error (uninitialized constant ActionView::CompiledTemplates::FormatUtilities)
So it thinks its a constant and not a class method, which is how it is defined. Any ideas?
class FormatUtilities
def self.slugify(name)
name.downcase.gsub(/\s|\W|\D/, "")
end
end
Thanks!

Turns out rails3 stop autoloading the lib directory. I have no idea why they did it, but they did. Just needed to add it to the autoload in the application.rb
thanks anyways!

Classes are constants in Ruby, besides also being classes. Probably you just need to do "require format_utilities"

You need to add:
# in config/application.rb
config.autoload_paths = %W(#{config.root}/lib
The name of your file should be format_utilities.rb for autoload to work.
In your particular case i would use a different aproach. Instead of creating a class with static functions i would create a module named FormattingHelper in app/helpers/formatting_helper.rb like this.
class FormattingHelper
def slugify(name)
name.downcase.gsub(/\s|\W|\D/, "")
end
end
Then in ApplcationController or in a specific controller i would add:
class ApplicationController < ActionController::Base
helper :formatting
end

If you want rails to automatically load this file when it boots, you will need to name your file format_utilities.rb. The next time you restart your server or console, you should be able to do FormatUtilities.slugify("name")

Related

How do I create my own method to change a string in Ruby on Rails? [duplicate]

I want to build an index for different objects in my Rails project and would like to add a 'count_occurences' method that I can call on String objects.
I saw I could do something like
class String
def self.count_occurences
do_something_here
end
end
What's the exact way to define this method, and where to put the code in my Rails project?
Thanks
You can define a new class in your application at lib/ext/string.rb and put this content in it:
class String
def to_magic
"magic"
end
end
To load this class, you will need to require it in your config/application.rb file or in an initializer. If you had many of these extensions, an initializer is better! The way to load it is simple:
require 'ext/string'
The to_magic method will then be available on instances of the String class inside your application / console, i.e.:
>> "not magic".to_magic
=> "magic"
No plugins necessary.
I know this is an old thread, but it doesn't seem as if the accepted solution works in Rails 4+ (at least not for me). Putting the extension rb file in to config/initializers worked.
Alternatively, you can add /lib to the Rails autoloader (in config/application.rb, in the Application class:
config.autoload_paths += %W(#{config.root}/lib)
require 'ext/string'
See this:
http://brettu.com/rails-ruby-tips-203-load-lib-files-in-rails-4/
When you want to extend some core class then you usually want to create a plugin (it is handy when need this code in another application). Here you can find a guide how to create a plugin http://guides.rubyonrails.org/plugins.html and point #3 show you how to extend String class: http://guides.rubyonrails.org/plugins.html#extending-core-classes

RAILS 4.1.4: My class in the lib folder loads as a module?

I've written a tiny game in the form of a Class. I've placed that file in the lib folder and I've set the appropriate loader in config/application.rb . But when I try to call Game.new in my controller it says undefined method 'new' for Game:Module. I want to be very clear THIS IS NOT A MODULE. Why the heck is it treating my class as a module? How can I fix it?
class Game
def initialize
end
end
See... this is a class with the .new method. It loads fine in IRB, but not in Rails.
I got it. It turns out I had named the class the same name as my rails project name. So it would only accept a module for that name. I renamed the class and file and now I'm good to go.

new to rails. going crazy when just trying to add a class and use it

hi i know i am new to rails.
i came from ASP.Net mvc
but although most of the stuff in rails are very easy to do sometimes the small things which are easy in .net makes you crazy in rails.
i have a rails app and im just trying to add a class. and use it in my controller. this class is just for holding data. not from the db. just a simple class for me to use
so i added the class file first in the "/libs/assests" folder. then i read i needed to add a line to the application.rb file that says to load the files from there
so i did..
config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
this still didn't work..
so ive put my class file in the regular Models folder. but it seem its still isn't working
this is my class code:
class Person
attr_accessor :name, :role
def initialize(name, role)
#name = name
#role = role
end
end
and in one of my controller is try to do this:
Person.new("name", "worker");
but i get this error:
uninitialized constant MainController::Person
what is the big deal?.. why is this so complicated to add a public class to a project?
thanks
You have to require the .rb file where the class is specified, you can do that with "require" or "require_relative":
http://rubylearning.com/satishtalim/including_other_files_in_ruby.html
In your Rails.root start up the console:
rails c
Just reference the class name:
Person
What do you see?
Without know much more, it looks like your load path might not be right. See what's in there:
puts $:.join("\n")
Lastly, brute forcing it might give you more info about the problem:
require Rails.root.join("app","models", "person")
This loads the file manually and skips the rails auto loading magic.

How to call methods of an external class in Ruby

I have a file under /lib with its own method.
# lib/file.rb
class File < ApplicationController
def my_method
...
end
end
However I can't reach the method through the console
ruby-1.9.2-p290 :044 > File.my_method
NoMethodError: undefined method `my_method' for File:Class
Any idea how?
my_method is an instance method of the File class. It means that you can call it only on the instance of the File class.
file = File.new
file.my_method
You can declare my_method as class method using def self.my_method syntax.
class File < ApplicationController
def self.my_method
...
end
end
File.my_method
But in class methods you can't use instance variables of the File object.
You're trying to call my_method as a class method, but you've defined it as an instance method.
You should either define it as def self.my_method, or create an instance of the controller to call it as an instance method.
In addition, you are going to run into problems for a couple of reasons - (1) Rails expects controllers to be named like FilesController, and (2) File is a class in the standard library. I would encourage you to change the class name to FilesController, and rename the file itself to files_controller.rb to prevent both issues.
Well... there are several interesting things going on with this example. The first would be that this class name is call File which is already defined in Ruby.
That is most likely why when you are in the console you didn't get an undefined class error. Since my_method is not defined on Ruby's File class, this is why you are seeing undefined method.
Now to your question. I would try naming your class something different first and trying again from lib. I believe it should be loaded by default again with the rails environment. For a version or two that functionality was taken out but I want to say it's back in. If not, just go into your config/application.rb file and look for a declaration along the lines of config.autoload_paths. Add the lib directory there and you should be good to go.
Lastly, is there a reason you want a controller in lib?

Uninitialized constant trying to reopen a Class

I am using a plugin in Rails, and I call its methods without problems:
plugin_module::class_inside_module.method_a(...)
I want to re-open the class_inside_module and add a new method, I tried in many different ways. I can't figure out why in this way doesn't work:
class plugin_module::class_inside_module
def new_method
puts 'new method'
end
end
I get the error: uninitialized constant plugin_module, but how is possible if I can call without problem plugin_module::class_inside_module.any_methods ?
Do you know why I get that error ? why "uninitialized constant" ? (it is a class declaration :-O )
Do you have any ideas how I can add a new methods in a class inside a module (that is part of a plugin) ?
Thank you,
Alessandro
If you have written your class and module-names like you did, so plugin_module instead of PluginModule this is against ruby/rails standards, and rails will not be able to automatically find the class and module.
If you write something like
module MyModule
class MyClass
end
end
Rails will expect this file to be located in lib\my_module\my_class.
But this can always easily be overwritten by explicitly doing a require.
So in your case, when you write
module plugin_module::class_inside_module
Rails will not know where to find the module plugin_module.
This way of writing only works if module plugin_module is previously defined (and loaded).
So either add the correct require, or rename your modules to standard rails naming, or write it as follows:
module plugin_module
class class_inside_module
This way will also work, because now the order no longer matters.
If the module is not known yet, this will define the module as well.
Either you are re-opening the class, or you define it first (and the actual definition will actually reopen it).
Hope this helps.
Have you tried reopening the module that's wrapping the class, rather than relying on ::?
module plugin_module
class class_inside_module
def new_method
puts 'new_method'
end
end
end
By the way, you know that the proper name for modules and classes is use CamelCase with a capital first letter?
module PluginModule
class ClassInsideModule
def new_method
puts 'new_method'
end
end
end

Resources