I'm trying to add a method to the DateTime class like so:
class DateTime
def ymd(sep = "/")
strftime("%Y#{sep}%m#{sep}%d")
end
end
I put this in #{config.root}/lib/datetime.rb and updated the autoload_path to include #{config.root}/lib (since that seems to go in and out of the conventional autoload path). That didn't work, so I also tried putting it in a random directory (#{config.root}/blah and added that path to the autoload_paths line in the config).
In all of the above cases, I'm only able to use the new method in the rails console if I require 'datetime' first, and I'm not able to use it in controllers or view templates no matter what I do.
So,
Should the file be called datetime.rb or date_time.rb? (I've tried both so far and neither are currently working)
Where should I be putting this file so I can use the new method in models, controllers and views?
Any idea why I can require it in the console, but it doesn't autoload there?
The app is currently running rails 3.2.21, but I'll switch to rails 4 at some point so answers for either version are appreciated.
Related
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
I would like to have a new method for Date class in my Ruby 2.0 Rails 4 application. Adding a new like 'date_extensions.rb' in /lib used to work in another Ruby 1.9 Rails 3.2 app but not here. The extension is pretty simple now:
class Date
def week_day
self.wday == 0 ? 7 : self.wday
end
end
I do not like to put it in initializer as it keeps growing. Is there a good workaround?
At some point, Rails stopped adding the lib directory to the autoload paths. The other app had probably set a setting to autoload the lib directory and your new app doesn't have that (yet?). So that's why you're having to require the file directly via an initializer. For what it's worth: I think this is the better approach -- only load code when you need it. I usually add a config/initializers/application.rb and then add requires such as require "date_extensions" in there. Then the date_extensions.rb file goes in the lib folder as you suggest.
I'm having a problem with a module name and the folder structure.
I have a model defined as
module API
module RESTv2
class User
end
end
end
The folder structure looks like
models/api/restv2/user.rb
When trying to access the class, I get an uninitialized constant error. However, if I change the module name to REST and the folder to /rest, I don't get the error.
I assume the problem has to do with the naming of the folder, and I've tried all different combos of /rest_v_2, /rest_v2, /restv_2, etc.
Any suggestions?
Rails uses the 'underscore' method on a module or class name to try and figure out what file to load when it comes across a constant it doesn't know yet. When you run your module through this method, it doesn't seem to give the most intuitive result:
"RESTv2".underscore
# => "res_tv2"
I'm not sure why underscore makes this choice, but I bet renaming your module dir to the above would fix your issue (though I think I'd prefer just renaming it to "RestV2 or RESTV2 so the directory name is sane).
You'll need to configure Rails to autoload in the subdirectories of the app/model directory. Put this in your config/application.rb:
config.autoload_paths += Dir["#{config.root}/app/models/**/"]
Then you should be able to autoload those files.
Also, your likely filename will have to be app/model/api/res_tv2/user.rb, as Rails uses String.underscore to determine the filename. I'd just call it API::V2::User to avoid headaches, unless you have more than one type of API.
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.
tl;dr
What's a simple way I can create a view helpers module I can use in many apps?
What file, located where, loaded how?
I'm on Rails 2.3.11.
I have a bunch of view helper methods. Here's an example of one of them:
# Render form input fields to add or edit a ZIP code.
def render_zip_code_fields( model_instance )
# Bla bla bla ...
end
I have about 20 or so that I've developed over the years and often use in various applications. I'd like to wrap them all up in one file that I can just drop into and app and then be able to call them in my views.
Why not just copy-and-paste them into application_helper.rb? That just doesn't feel right to me. It seems like it should be a separate file.
In fact I tried creating in /lib...
# /lib/my_view_helpers.rb
module MyViewHelpers
# ...
end
And then in application_helper.rb I put...
include MyViewHelpers
But I got a lot of "uninitialized constant MyViewHelpers errors. Maybe a syntax error? I don't think I need to require my_view_helpers.rb first because it's in /lib. Everything in there gets loaded automatically, right?
So what's the right way to do this optimizing for simplicity?
Sorry this is so long. I get verbose when I'm tired.
As of Rails 3, /lib is no longer on the default load path. You will need to put the following line in the Application class in config/application.rb.
config.autoload_paths += ["#{config.root}/lib"]
An alternative would be to drop the file in app/helpers since it is a helper, after all.