I am using Ruby on Rails 3.0.9 and I am trying to make it possible to call some methods from all inside helper, controller, models and view files. What I would like to make is to create a library to build\standardize naming conventions internally to my application so that I can use\run something like the following:
standardized_name = standardize_name(Article)
What do you advice about?
P.S.: I have heard of mixin, but how should I use those in my case? Furthermore I would like not to state inclusion of that mixin in each class that need to use that (that is, I would like to have a "unique" statement that includes the mixin in all my application classes).
A similar library that's accessible in all layers of the Rails MVC is I18n. You can call the translate method with I18n.t while there's a helper t method in the view and controller layer so you don't need to type the entire "I18n.t" every time.
We can follow how I18n did it. You can create a module in the lib directory of your application. Make sure to update application.rb so that your module is loaded. Look for this comment in application.rb:
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
Obviously, if you uncomment the autoload_paths line, change "extras" to "lib".
Here's an example module lib/Karate.rb:
module Karate
class << self
def punch(grunt)
puts "#{grunt}! *punch*"
end
end
end
Now you can call this anywhere in your application:
Karate.punch("boom")
# => boom! *punch*
If you want a helper method in your View and Controller layers, just add a method in application_controller.rb:
def punch(grunt)
Karate.punch(grunt)
end
And declare this method as a helper method (also in application_controller.rb), like so:
helper_method :punch
BUT, please make sure you really need this library. I didn't question your reason because it will not answer your main question. I think you should just practice your naming convention in your code, add it in README if you have to or send an email to your team. Also, Rails and Ruby has naming conventions already, so be sure to learn about it as well.
Depending on your use case, you can take one of these approaches to rather attach the method to the objects it acts on. Then you don't need to include the standardize_name
method everywhere you want to use it; you just centralized it on the objects to which it applies:
If your standardize_name
method only takes ActiveRecord models as arguments, consider putting it in a module (in lib/standardizable.rb
for example) and extending it onto ActiveRecord::Base
(or some other class that is a parent to all your domain classes):
module Standardizable
def standardized_name
# in here, self will be the model *class*,
# so the following will return "Article" if you
# extended the module into the Article class:
self.name
end
end
# include the mixin in all ActiveRecord models:
ActiveRecord::Base.extend Standardizable
Alternatively, if you don't want to include it in all models, just include the module into the individual classes where you want standardized_name
to be available:
class Article < ActiveRecord::Base
extend Standardizable
end
With both of the following approaches, you will be able to use the method like so:
standardized_name = Article.standardized_name
If you'd rather use the method on instances of your model classes, just change extend
in the above example to include
:
module Standardizable
def standardized_name
# in here, self will be the model object *instance*,
# so the following will return "Article" if you
# included the module into the Article class:
self.class.name
end
end
# include the mixin in all ActiveRecord models:
ActiveRecord::Base.send(:include, Standardizable)
The usage then looks like this:
article = Article.new
standardized_name = article.standardized_name
A nice way to wrap up both these approaches in Rails 3 is with ActiveSupport::Concern
:
module Standardizable
extend ActiveSupport::Concern
module ClassMethods
def standardized_name
self.name
end
end
module InstanceMethods
def standardized_name
self.class.standardized_name
end
end
end
ActiveRecord::Base.extend Standardizable
Then you can use both the class and instance method to get the standardized name:
standardized_name_from_class = Article.standardized_name
article = Article.new
standardized_name_from_instance = article.standardized_name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With