I am having a action in application controller
def is_customer_logged_in?
!!session[:customer_id]
end
And in my view am trying to access the application_controller action like this
<% unless is_customer_logged_in? %>
some functions
<% end %>
The above code is a partial layouts.
This is the error message I am facing
undefined method `is_customer_logged_in?' for #<#<Class:0xb51a5300>:0xb5616484>
You can define it to be a helper method and you should be able to access that method in the view.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def is_customer_logged_in?
!!session[:customer_id]
end
helper_method :is_customer_logged_in?
end
try helper_method: is_customer_logged_in?
Related
I am using a presenter for a view in rails to display data which is saved in a yml file. (i18n gem)
This is the controller-
class DocumentsController < ApplicationController
def index
#presenter = DocumentPresenter.new
end
end
This is my view-
= #presenter.viewname
and this is my presenter-
class DocumentPresenter
def viewname
content_for :secondary_nav_title do
t('Documents')
end
end
end
The error says:
undefined method `content_for'
Why doesn't rails recognize content_for in the presenter?
the content_for helper method should not be used in your model as this violates the MVC pattern.
if you must use it, though this is not reccomended, you can add this at the bottom of your model.
def helpers
ActionController::Base.helpers
end
Then to call content_for you would use
class DocumentPresenter
def viewname
helpers.content_for :secondary_nav_title do
t('Documents')
end
end
end
I've a sidebard to display #notices
<% #notices.each do |notice| %>
<li class="list-group-item notice"><%= short_auto_link(notice.content) %></li>
<% end %>
I also have a admin interface to manage notices(e.g. CRUD).
The problem is that when I open edit or new page for notice.
It will report undefined method 'each' for nil:NilClass for <% #notices.each do |notice| %>.
Now I can only get away with this by adding a <% if #notices %> before the .each block.
UPDATE:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_notice
def set_notice
#notices = Notice.all
end
end
app/views/notices/_notice_board.html.erb:8:in `_app_views_notices__notice_board_html_erb__624099781_29657256'
app/views/layouts/application.html.erb:19:in `_app_views_layouts_application_html_erb___900927418_28913616'
You need to change this:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_notice
def set_notice
#notices = Notice.all
end
end
to this:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_notices
def set_notices
#notices = Notice.all
end
end
Things you can learn from this is that always try to avoid such naming conventions of a method. Since, you're setting #notices(plural), your method name should also be plural: set_notices. In your case set_notice method is being overridden by method defined with the same name in NoticesController. Changing the method name as mentioned above should fix the issue.
If your sidebar is shared only across all actions of your admins_controller define a private method to get #notices in admins_controller, and put before_filter at the beginning of the controller.
in admins_controller ::
before_filter :prepare_notices
def show
end
def edit
end
...
private
def prepare_notices
#notices = YOUR_QUERY
end
If your sidebar will be rendered across the whole website move the code to your application_controller and before any request to you server this method will be executed.
If your sidebar will be rendered with some actions in your website you should put the get_notices method in the application_controller and use before_filter in each controller specifying the actions that will render the sidebar only.
Within my application.html.erb, I want to be able to detect if the currently rendering page is from within a mounted engine (Forem, if that matters), so that I can add an active class to the nav bar. Is there an easy way to detect this?
I'm using Rails 3.2.
You could add a helper method in Forem::ApplicationController by reopening the class:
Forem::ApplicationController.class_eval do
def forem?
true
end
helper_method :forem?
end
Add the above file in app/decorators/forem/application_controller_decorator.rb for example.
This way every time a view is rendered by Forem's controller you would be able to call forem? within your view.
application.html.erb
<% if forem? %>
# do something
<% end %>
You might want to check if the current instance respond_to?(:forem?) first, or add a forem? method returning false in your own application_controller.rb.
A very similar approach can be done without the use of decorator loading (just using Rails default loading), e.g. for Thredded:
#This file would be at app/controllers/thredded/application_controller.rb in your main_app repo
require_dependency File.expand_path("../../app/controllers/thredded/application_controller",
Thredded::Engine.called_from)
module Thredded
class ApplicationController < ::ApplicationController
def thredded?
true
end
end
end
and then add the default value and helper_method declaration in your own ApplicationController:
class ApplicationController < ActionController::Base
helper_method :thredded?
def thredded?
false
end
# etc
end
You can use this:
<% if controller.controller_name == ""something" &&
controller.action_name == "something" %>
Do someting <!-- add you class -->
<% end %>
i have a problem:
undefined method `avatar_url' for #<User:0x000000040783a8>
controller:
class ApplicationController < ActionController::Base
protect_from_forgery
helper :all
helper_method :avatar_url
protected
def avatar_url(user)
if user.avatar_url.present?
user.avatar_url
else
default_url = "#{root_url}images/guest.png"
gravatar_id = Digest::MD5.hexdigest(user.email.downcase)
"http://gravatar.com/avatar/#{gravatar_id}.png?s=48&d=#{CGI.escape(default_url)}"
end
end
end
in view:
...
<%for user in #users %>
<%= image_tag avatar_url(user) %>, username: <%= user.username %>, e-mail: <%= user.email %>
<% end %>
...
Someone help me?
The key is the error message:
undefined method `avatar_url' for #<User:0x000000040783a8>
The error isn't because the helper method is undefined: the error message indicates it's a missing method in the User class. The method defined in ApplicationController attempts:
def avatar_url(user)
if user.avatar_url.present?
user.avatar_url
#...
You need to make sure the User class has an avatar_url instance method.
Better you can remove the line "helper_method :avatar_url" from the file ApplicationController.
Please see more details here. "undefined method" when calling helper method from controller in Rails
Because, you should define the helper method xxx (helper_method :xxx) in any other module/helper file. So, the line helper :all automatically include all your helper files then only you can use the line helper_method :xxx. It makes sense.
No need to define the ApplicationController methods as a helper method. You can call those methods in any controller or views in simply avatar_url().
I defined a helper class as below
module SessionsHelper
def current_user
#current_user= User.find_by_fbid(session[:fbid])
end
def sign_in(user)
session[:fbid] = user.fbid
#current_user = user
end
def signed_in?
!current_user.nil?
end
end
I included the Helper Class in my Application Controller
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
The sign in method gets called from Session Controller
class SessionsController < ApplicationController
def create
user = User.find_or_create_by_fbid(params[:user][:fbid])
user.update_attributes(params[:user])
sign_in(user)
redirect_to user_path(user)
end
end
However I am not able to access 'current_user' variable from users#show view.
<% if signed_in? %>
<p>
<b>Current User:</b>
<%= current_user.name %>
</p>
<% end %>
It says : undefined method `name' for nil:NilClass
Can anyone please advise ?
The method current_user does not get called at all from index.
Putting include SessionsHelper in your controller includes those module methods in the controller, so they are accessible in your controller methods. You want the helper methods available in your views, so you need to use helper SessionsHelper in your application controller.
That being said, I do agree with Jits that the methods you have in SessionsHelper really do belong in the controller instead of in a helper.
Generally you should have methods like current_user defined in your application_controller and then make them available as helpers in the views. This way the controllers have access to them (and trust me, you will most likely need access to things like that). Example:
def current_user
..
end
helper :current_user
What helped me:
Define methods to use in the controller in helper files
Define methods to use in the view in the relevant model file
Example
Suppose you had this in user_helper.rb
def something
2 + 2
end
simply move that code into
models/user.rb
and it will be accessible in the view without any further effort.