I have an easy question:
Where to put the helper methods that is called many times by a controller ?
My wish is to keep clear my controller ( user_controller) and I have an helper methods that is called many times (check_permits)
is it possible to put this method inside user_helper ?
If yes ==> how to recall it inside user_controller ? If I simply recall check_permits it doesen't recognize it.
If no ==>, where to put the helper methods ?
You are using confusing terminology. In rails, controllers do not have helpers. Helpers are defined as being for the views. It's possible to call helper methods from a controller by using the "helpers" method (see http://api.rubyonrails.org/classes/ActionController/Helpers/ClassMethods.html), but I don't think that's what you're looking for (and generally that's not a good idea anyway).
What you probably want is to either (1) put the method directly in your users_controller.rb as a protected method:
class UsersController < ApplicationController
...
protected
def check_permits
...
end
end
Or (2) put it in the application_controller.rb if you call it from multiple controllers.
Or (3) put it in a library file as a module and include it in whatever controllers need it. For example, you might create lib/check_permits.rb:
module CheckPermits
protected
def check_permits
...
end
end
And then in users_controller.rb:
class UsersController < ApplicationController
include CheckPermits
...
end
You can put global helper methods in the application_helper.rb file, but if it's only to be used by one controller each controller can have it's own helper file. Look in app/helper (or app/controller/helper).
Related
I have some helpers that are defined on runtime that are specific for a single call, e.g. a single instance of a controller (the next call could have different helper methods). Is there a robust way to add a helper method to an instance of a controller and it's view only, without adding the helper to other instances and views of this controller?
To define a helper for ALL instances, you could use the .helper_method method, e.g.
class Article < ApplicationController
helper_method :my_helper
def my_helper
# do something
end
end
I digged around in the source code, and found the (fairly private looking) #_helpers method which returns a module that contains all helpers for this instance. I could now use some meta programming to define my methods on this module
def index
_helpers.define_singleton_method(:my_helper) do
# do something
end
end
But I don't like this approach because I'm using a clearly private intended method that could easily change in the future (see the leading _).
If I only needed the helper inside the controller instance only, I could just call #define_singleton_method on the instance directly, but this doesn't make it available to the view.
So I'm looking for an official "Rails way" to define a helper for a single instance of a controller and it's view, like Rails provides with it's class method .helper_method.
I'm not sure if there is an official Rails way of doing this.
You could create an anonymous module and extend from that. Since this solution uses pure Ruby, you'll have to extend both the controller and view.
before_action :set_helpers, only: :index
def index
# ...
end
private
def set_helpers
#helpers = Module.new do |mod|
define_method(:my_helper) do
# do something
end
end
extend(#helpers)
end
<% extend(#helpers) %>
In my rails app I have a method that will be used in different Views, Controllers and in different Workers as well so what is best place to define this method such that code would not be get repeated.
In lib directory you can create module and define a method over there so you can access that method anywhere.
Best place is Helper, define it in application_helper.rb
module ApplicationHelper
def printing
"Printing..."
end
end
and include it in ApplicationController
class ApplicationController < ActionController::Base
include ApplicationHelper
end
Current I have three controllers that uses the exact same authorize_journey method (located in the controllers). Each controller also calls the exact same before_filter :authorize_journey. What is the best way to reduce this kind of redundancy through best-practice?
Also, how can I, if possible, stick to the fat-model-skinny-controller practice?
If the authorize_journey methods are all identical, then you can move a copy to '~/app/controllers/application_controller.rb' and remove it from all the individual controllers.
The before_filters can all remain as they are.
Of course, if the methods are not identical, you may require some refactoring to generalize it further. If you post the code, we can comment further.
You can always use it in the application_controller.rb.
Move the authorize_journey method to application_controller.
Say if you have 4 controllers and you need the before_filter in 3 controller. Then you can define the before_filter :authorize_journey in the the application_controller and use:
skip_before_filter :authorize_journey
in the 4th controller where you don't want the before_filter
I would suggest adding the method to a concern and include them in the controllers that requires the authorize_journey before_filter.
Code for concern will be:
# controllers/concerns/authorize_journery.rb
module AuthorizeJourney
extend ActiveSupport::Concern
included do
before_filter :authorize_journey
end
protected
def authorize_journey
# Code goes here
end
end
Now in the controllers, include the AuthorizeJourney module.
# controllers/examples_controller.rb
class ExamplesController < ApplicationController
include AuthorizeJourney
# Code goes here
end
I'm new to rails and I have this small problem about helpers and controllers. Is it possible to include my custom helper to a controller?
Let's say I have this helper class.
Module UsersHelper
def my_helper
...
end
end
Then I have this controller.
class UsersController < ApplicationController
end
Can I use the my_helper in my controller?
Yes - There are several ways, not least including (mixing-in) the helper into the controller, or using the loophole explained here
But... if it's hard to do, or results in ugly code, it may not be the right way to do it. Can the method that's in the helper not be moved into the controller, and then delegated back to the helper using "helper_method"?
Yes. you can do by using include, but I don't recommend you doing this. Because Rails constructs under MVC architecture, you can learn more about MVC before include UserHelper in your controllers.
MVC Reference:
http://guides.rubyonrails.org/getting_started.html#the-mvc-architecture
Model–view–controller
If I want to have functions to be called inside controllers, where should I put them?
if you want it to be local to a controller then all you need to do is to add it to the controller you wish to use.
private
def myfunction
function code.....
end
to all controllers you can put it inside the application controller, because all controlers are sub classed.
ApplicationController
protected
def myfunction
function code.....
end
If you want access in your views then you can create a helper
ApplicationHelper
def myfunction
function code...
end
#jonnii, for example, I want to call a function that returns a generated unique code.
If your generated code is going to be used only on your controllers, put the function inside a controller, as protected function (the easiest way would be putting it inside ApplicationController).
If you need to call the function on the views, then put it on a helper, like ddayan says.
If you also need to invoke the function from models, then the simplest way to do it is by putting a module inside the /lib/ directory.
# /lib/my_module.rb
module MyModule
def generate_code
1
end
end
You will also need to include it with an initializer:
#/config/initializers/my_module.rb
require 'my_module'
From that moment on, you can use the function like this:
MyModule::generate_code
If you are doing this very often, consider creating a gem.
class YourController < ActionController::Base
def your_action
your_function
end
private
def your_function
end
end
Also look at before_filter and after_filter, they're often useful in such kind of things
The ApplicationController is here for that, since every Controller inherited from it.