rails "undefined method" when invoking a helper method from layout view
I have an helper method in to get the current shopping cart in my application controller:
class ApplicationController < ActionController::Base
protect_from_forgery
helper :all # include all helpers, all the time
private
def current_cart
if session[:cart_id]
@current_cart ||= Cart.find(session[:cart_id])
session[:cart_id] = nil if @current_cart.purchased_at
end
if session[:cart_id].nil?
@current_cart = Cart.create!
session[:cart_id] = @current_cart.id
end
@current_cart
end
end
I can call the method from m开发者_运维百科ost of my views, but I want to use it in the views/layout/application.html.erb file, like this:
<div id="cart_menu">
<ul>
<li>
<%= image_tag("cart.jpg")%>
</li>
<li>
<%= link_to "#{current_cart.number_of_items}", current_cart_url %>
</li>
<li>
<a href="/checkout/">Checkout</a>
</li>
</ul>
</div>
But when I try that, I get an
undefined local variable or method `current_cart' for #<#<Class:0x2d2d834>:0x2d2b908>
error..
Any ideas whyis that?
Add helper_method :current_cart
to your application controller.
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_cart
...
end
Your example fail because you define the method current_cart
in the ApplicationController but controller method are not accessible in the view.
There are two ways to achieve what you want :
The first way is to move the method current_cart
in an helper.
The second way will be to set the variable @current_cart
with a before_filter
and use @current_cart
in the view, see below :
class ApplicationController < ActionController::Base
protect_from_forgery
helper :all # include all helpers, all the time
before_filter :set_current_cart
private
def set_current_cart
if session[:cart_id]
@current_cart ||= Cart.find(session[:cart_id])
session[:cart_id] = nil if @current_cart.purchased_at
end
if session[:cart_id].nil?
@current_cart = Cart.create!
session[:cart_id] = @current_cart.id
end
end
end
In your view :
<%= link_to "#{@current_cart.number_of_items}", current_cart_url %>
Helper methods belong to the helper modules, e.g. in app/helpers/application_helper.rb
I'm actually not sure, why this works in other views, but I think, as a site-wide logic, you should define it as a before_filter for ApplicationController. If you only need it in one controller, put it there.
And it's not a "helpers". Helpers are stored in app/helpers
and are usually used to simplify views by hiding some html inside it's methods.
精彩评论