Access request object in rails helper - ruby-on-rails

In my application_helper.rb file I have a function like this:
def find_subdomain
request.domain
end
undefined local variable or method `request'
And I am invoking this method in another helper. How can i get the domain in helper without passing any argument from controller.

I know this is old, but having stumbled across this myself recently I thought I'd chip in. You could add the method to your ApplicationController and specify it as a helper_method instead:
class ApplicationController < ActionController::Base
helper_method :find_subdomain
private
def find_subdomain
request.domain
end
end

As others have mentioned, the request object should be passed to your helper, which would let you pass it from the view (ERB) as follows,
<%= find_subdomain(request) %>

class ApplicationController < ActionController::Base
helper :all
end

Related

Rails, def or constant to symbol

In my application_controller.rb I have this code:
def current_resource
if admin_signed_in?
:admin
elsif partner_signed_in?
:partner
end
end
Now I want to pass this def to child controllers like this:
authorize_resource current_resource
However it throws me an error. undefined local variable or methodcurrent_resource'`
How I can pass this current_resource to its child controllers as symbol.
That is how I call it inside controller:
class PageController < ApplicationController
authorize_resource current_resource
end
current_resource is inside application_controller
You're attempted to invoke an instance method on the class. You cannot do this.
If you want to invoke the method without an instance, you need to declare it on self:
def self.current_resource
if admin_signed_in?
:admin
elsif partner_signed_in?
:partner
end
end
This will still likely not work, unless each of the methods used inside that method are also declared as class-level methods.
This code:
class PageController < ApplicationController
authorize_resource current_resource
end
will be executed during PageController class loading, not during request handling. So you can't call admin_signed_in? and partner_signed_in? then. Also I don't know why are you trying to call authorize_resource with argument, because it doesn't get arguments, check cancancan source.
I think you have misunderstood how cancan filters and abilities work. You shouldn't pass User model to the filter. User type should be checked in Ability class and based on that, proper permissions should be selected. In your controller (btw. it should be PagesController) you only load resources and authorize them, ie.:
class PagesController < ApplicationController
load_resource
authorize_resource
# or just load_and_authorize_resource
end
You can customize how resources will be loaded and authorized. Please read this about authorizing controller actions and those examples. And also please read this about defining abilities.

Class variables with params values in ApplicationController

In appllication controller i have couple of methods that works with requested controller and action name.
To follow DRY principe, i want to define share variables with those params.
class ApplicationController < ActionController::Base
##requested_action = params[:action]
##requested_controller = params[:controller]
end
But i get error: undefined local variable or method "params" for ApplicationController:Class
Why i can't do this and how can i achieve my goal?
I believe you already have controller_name and action_name variables defined by Rails for this purpose.
If you want to do it by your way, you must define it as a before filter as params comes to existence only after the request is made. You can do something like this
class ApplicationController < ActionController::Base
before_filter :set_action_and_controller
def set_action_and_controller
#controller_name = params[:controller]
#action_name = params[:action]
end
end
You can access them as #controller_name and #action_name. But controller_name and action_name are already defined in Rails. You can use them directly.
Use instance methods instead:
class ApplicationController < ActionController::Base
def requested_action
params[:action] if params
end
end
You can use before_filter option.
class ApplicationController < ActionController::Base
before_filter :set_share_variable
protected
def set_share_variable
#requested_action = params[:action]
#requested_controller = params[:controller]
end
end

rails: how do i access a method in my application controller?

Noob scoping issue, I imagine. :\
class ApplicationController < ActionController::Base
protect_from_forgery
#locations = get_locations
def get_locations
Location.where(:active => true).order('name').all
end
end
Error:
undefined local variable or method `get_locations' for ApplicationController:Class
Two questions:
1) What's with the error? Am I calling the method incorrectly?
2) How do I access this method from a sub-classed controller?
You're calling get_locations within the class scope, but the method is an instance method, not a class method. If for example you used def self.get_locations then you would be providing a class method, one of which you can use within the class scope (after you have defined it, not before like you're doing).
The problem here is the logic, what is this method for? What do you intend to use #locations for? If it's to go inside your application view, then you should put this method into the ApplicationHelper module, and call it from inside the relevant action. If you'd like it in another view on another controller and you'd like to use #locations inside your locations method, perhaps your setup might look something like this:
PagesController
class PagesController < ActionController::Base
def locations
#locations = Location.where(:active => true).order('name').all
end
end
locations.html.erb
<% #locations.each do |location| %>
<%= # do something with 'location' %>
<% end %>
If you'd like to use this inside of your application.html.erb you can simplify it quite some..
ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery
def locations
Location.where(:active => true).order('name').all
end
end
application.html.erb
<% locations.each do |location| %>
<%= # do something with location %>
<% end %>
The answer boils down to logic, and to really figure out exactly what you're looking for, more details would probably be required.
You're calling it from the class scope, not from an instance scope. more likely what you want is the following:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :setup_locations
private
def setup_locations
#locations = Location.where(:active => true).order('name').all
end
end
To make your original example work, you'd need to make #get_locations defined on self (which points to the class at definition), like so:
class ApplicationController < ActionController::Base
protect_from_forgery
#locations = get_locations
def self.get_locations
Location.where(:active => true).order('name').all
end
end
The problem with that code is that #locations will only be available from the class level as a class instance variable, which is comparable to a static variable in most other languages, and which probably isn't what you want.
I imagine that this line:
#locations = get_locations
... is trying to access the class level method get_locations and not the instance method.
The clue here is that the error message is showing that it can't find it on the class itself (ApplicationController:Class) and not an instance of that class. That means that you're in the class scope, not instance scope.
This would fix it:
def self.get_locations
Location.where(:active => true).order('name').all
end
Even the question is quite old, you can also call your controller action anywhere just by calling:
ApplicationController.new.get_locations

how to call a helper method from both view and controller in rails?

I created a helper method for some simple calculation. This helper method will just return an integer. I need the helper in both controllers and views.
Unfortunately, it work well in views but not in controllers. I get the undefined local variable or method error. How can I fix it?
Thanks all
In order to use same methods in both controller and views Add you method in application_controller.rb and make it helper methods.
For example
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
#protect_from_forgery # See ActionController::RequestForgeryProtection for details
helper_method :current_user
def current_user
session[:user]
end
end
Now you can use method current_user in both controllers & views
I use a following solution. Because I think helper's methods shoud be stored in an appropriate helper module.
module TestHelper
def my_helper_method
#something
end
end
class SomeController < ApplicationController
def index
template.my_helper_method
end
end

"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