Difference between stating helper methods in helper and controller files - ruby-on-rails

In Ruby on Rails we can state a helper method in controllers e.g.
# app/controllers/my_controller.rb
class MyController < ApplicationController
helper_method :helper_method_name
...
private
def helper_method_name
...
end
end
and in helpers e.g.
# app/helpers/my_helper.rb
class MyHelper
def helper_method_name
...
end
end
What's the difference (in relation to access, usage, etc.)?

The method helper_method is to explicitly share some methods defined in the controller to make them available for the view.
This is used for any method that you need to access from both controllers and helpers/views (standard helper methods are not available in controllers).

As ray said. You only want to use the helper_method when you really need to use it in both the controllers and helpers/views.
Generally, you want to use controller concerns and the helpers(views) for the respective methods as that's the convention.

Related

Where should I store common function at?

I have three models.
users_controllers.rb
communities_controller.rb
community_tipics_controller.rb
I'm using the function called check_digit
def checkdigit
(transaction)
end
and I'm placing this in all the controllers.and calling it by before_filter.
But I think I'm wasting because I'm just pasting exactly the same code above to all of the controllers.
Where am I supposed to put it if my controller is using it in common?
Should I put it in controllers/application_controller.rb?
There are several ways of doing this , some possible ways are (If I'm to do this)
1st method
If this is a simple method used by controllers
inside application_controller.rb
private
def checkdigit
(transaction)
end
2nd method
if your function is used by a specific category , (this is normally I do very often), create a separate controller and have your all other controllers inherited by it
Ex: if your method used only my admins, and assuming you have some more methods like that
class AdminController < ApplicationController
layout 'admin'
private
def checkdigit
(transaction)
end
end
and
class UsersController < AdminController
end
3rd method
If your method is/will used by models/controllers etc.. consider making it a module
module CommonMethods
def checkdigit
(transaction)
end
end
class UsersController < ApplicationController
include CommonMethods
end
HTH
You can put it in helpers/application_helper.rb
You are correct, all common methods that all controllers need should be stored in the ApplicationController.
Furthermore, you should also keep common logic between all controllers in this controller.
Edit:
If they are just helpers, then you would put them where the helpers go, see the answer by #simone.

Where to put Ruby helper methods for Rails controllers?

I have some Ruby methods certain (or all) controllers need. I tried putting them in /app/helpers/application_helper.rb. I've used that for methods to be used in views. But controllers don't see those methods. Is there another place I should put them or do I need to access those helper methods differently?
Using latest stable Rails.
You should define the method inside ApplicationController.
For Rails 4 onwards, concerns are the way to go. There was a decent article which can still be viewed via the Wayback Machine.
In essence, if you look in your controllers folder you should see a concerns sub-folder. Create a module in there along these lines
module EventsHelper
def do_something
end
end
Then, in the controller just include it
class BadgeController < ApplicationController
include EventsHelper
...
end
you should define methods inside application controller, if you have few methods then you can do as follow
class ApplicationController < ActionController::Base
helper_method :first_method
helper_method :second_method
def first_method
... #your code
end
def second_method
... #your code
end
end
You can also include helper files as follow
class YourController < ApplicationController
include OneHelper
include TwoHelper
end
You can call any helper methods from a controller using the view_context, e.g.
view_context.my_helper_method
Ryan Bigg response is good.
Other possible solution is add helpers to your controller:
class YourController < ApplicationController
include OneHelper
include TwoHelper
end
Best Regards!
Including helpers in controller will end-up exposing helper methods as actions!
# With new rails (>= 5)
helpers.my_helper_method
# For console
helper.my_helper_method

Rails: Scope: making a method available to all Views and Controllers

I've struggled with scope for a few days. I would like to have a small number of methods available to ALL Views and Controllers.
Suppose the code is:
def login_role
if current_user
return current_user.role
end
return nil
end
If I include it in application_helper.rb, then it's only available to all Views, but not available to all Controllers
If I include it in application_controller.rb, then it's available to all Controllers, but not available to all Views.
Use the helper_method method in your ApplicationController to give the views access.
class ApplicationController < ActionController::Base
helper_method :login_role
def login_role
current_user ? current_user.role : nil
end
end
Consider putting all the related methods in their own module then you may make them all available like this:
helper LoginMethods
Create your own library (it could have classes, modules, methods), and put it in the lib directory. Let's call it my_lib.rb.
In your application_controller.rb, and application_helper.rb add the following line:
require 'my_lib'
This will make all the classes, modules, methods available to all Views and Controllers

Rails: Where to define a helper method that will be available to several controllers?

I would like to define a helper method, my_method, that will be available inside BuyersController methods (like index, create, e.t.c.).
I tried to define it in app/helpers/application_helper.rb but it didn't work:
undefined method `my_method' for #<BuyersController:0x26df468>
It should be in some shared place because I want to use it in other controllers also. This is why I tried app/helpers/application_helper.rb.
What is the right place to define it ?
It should be in app/controllers/application_controller.rb
The app/helpers/application_helper.rb is for shared view helpers.
You should include the application helper module in your application controller so that its methods will be available everywhere (all controllers and views) during a request.
class ApplicationController < ActionController::Base
helper ApplicationHelper
…
end
See the API docs for the helper method
Starting from Rails 3 you could also call view_context.my_method inside your controller
Expanding on the accepted answer, if you did want to share a controller method with views, helper_method seems well suited for this. Declaring a helper_method in the controller makes it accessible to the views.
class ApplicationController < ActionController::Base
helper_method :current_user, :logged_in?
def current_user
#current_user ||= User.find_by(id: session[:user])
end
def logged_in?
current_user != nil
end
end
Before rails 4, helpers with the same controller names will be only available in their controllers and views. Starting from rails 4, all helpers are available for all controllers (if you included them) and views. With that said, all helpers will be shared across your views.
Note: if you don't want this behavior for specific controllers, you can use clear_helpers, it will only include the helper with the same controller name.
For more information about using helpers see this

"undefined method" when calling helper method from controller in Rails

Does anyone know why I get
undefined method `my_method' for #<MyController:0x1043a7410>
when I call my_method("string") from within my ApplicationController subclass? My controller looks like
class MyController < ApplicationController
def show
#value = my_method(params[:string])
end
end
and my helper
module ApplicationHelper
def my_method(string)
return string
end
end
and finally, ApplicationController
class ApplicationController < ActionController::Base
after_filter :set_content_type
helper :all
helper_method :current_user_session, :current_user
filter_parameter_logging :password
protect_from_forgery # See ActionController::RequestForgeryProtection for details
You cannot call helpers from controllers. Your best bet is to create the method in ApplicationController if it needs to be used in multiple controllers.
EDIT: to be clear, I think a lot of the confusion (correct me if I'm wrong) stems from the helper :all call. helper :all really just includes all of your helpers for use under any controller on the view side. In much earlier versions of Rails, the namespacing of the helpers determined which controllers' views could use the helpers.
I hope this helps.
view_context is your friend, http://apidock.com/rails/AbstractController/Rendering/view_context
if you wanna share methods between controller and view you have further options:
use view_context
define it in the controller and make available in view by the helper_method class method http://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method
define it in a shared module and include/extend
Include ApplicationHelper in application_controller.rb file like this:
class ApplicationController < ActionController::Base
protect_from_forgery
include ApplicationHelper
end
This way all the methods defined in application_helper.rb file will be available in the controller.
You can also include individual helpers in individual controllers.
Maybe I'm wrong, but aren't the helpers just for views? Usually if you need a function in a controller, you put it into ApplicationController as every function there is available in its childclasses.
As said by gamecreature in this post:
In Rails 2 use the #template variable.
In Rails 3 use the controller method view_context
helpers are for views, but adding a line of code to include that helper file in ApplicationController.rb can take care of your problem. in your case, insert the following line in ApplicationController.rb:
include ApplicationHelper
As far as i know, helper :all makes the helpers available in the views...
Try appending module_function(*instance_methods) in your helper modules, after which you could directly call those methods on the module itself.
though its not a good practice to call helpers in controller since helpers are meant to be used at views
the best way to use the helpers in controller is to make a helper method in application_controller and call them to the controller,
but even if it is required to call the helper in a controller
then Just include the helper in the controller
class ControllerName < ApplicationController
include HelperName
...callback statements..
and call the helper methods directly to the controller
module OffersHelper
def generate_qr_code(text)
require 'barby'
require 'barby/barcode'
require 'barby/barcode/qr_code'
require 'barby/outputter/png_outputter'
barcode = Barby::QrCode.new(text, level: :q, size: 5)
base64_output = Base64.encode64(barcode.to_png({ xdim: 5 }))
"data:image/png;base64,#{base64_output}"
end
Controller
class ControllerName < ApplicationController
include OffersHelper
def new
generate_qr_code('Example Text')
end
end
hope this helps !
I had the same problem...
you can hack/bodge around it, put that logic into a model, or make a class specially for it. Models are accessible to controllers, unlike those pesky helper methods.
Here is my "rag.rb" model
class Rag < ActiveRecord::Base
belongs_to :report
def miaow()
cat = "catattack"
end
end
Here is part of my "rags_controller.rb" controller
def update
#rag = Rag.find(params[:id])
puts #rag.miaow()
...
This gave a catattack on the terminal, after I clicked "update".
Given an instantiation, methods in the model can be called. Replace catattack with some codes. (This is the best I have so far)
:helper all only opens helpers up to views.
This shows how to make a class and call it.
http://railscasts.com/episodes/101-refactoring-out-helper-object?autoplay=true
Try this to access helper function directly from your controllers view_context.helper_name
You can include your helper methods into a controller with a helper keyword syntax
class MyController < ApplicationController
helper ApplicationHelper
end

Resources