问题
I'm having a hard time figuring out how to incorporate multiple controller's logic into a sidebar.
For example, I want to have a section in the sidebar that uses @habits
logic from the habits_controller and a section that uses @unaccomplished_goals
logic from the goals_controller.
For this question let's just focus on @unaccomplished_goals
.
<% @top_3_goals.each do |goal| %>
shows correctly in the app's sidebar, which is derived from the goals_controller #index @top_3_goals = @unaccomplished_goals.top_3
BUT if I click on links goals/new or goals/1/edit I get the dreaded: undefined method each for nil:NilClass
!
Here's a view breakdown:
I use <%= render 'sidebar/sidebar' %>
in views/layouts/application.html.erb
to grab views/sidebar/_sidebar.html.erb
in order to use <%= render 'goals/upcoming' %>
to grab views/goals/_upcoming.html.erb
views/goals/_upcoming.html.erb
<table>
<% @top_3_goals.each do |goal| %>
<tr>
<td>
<strong>
<%= link_to goal.name, edit_goal_path(goal) %>
</strong>
</td>
<td>
<%= goal.deadline.strftime("%m-%d-%Y") %>
</td>
</tr>
<% end %>
</table>
views/sidebar/_sidebar.html.erb
<div id="sidebarsection" class="panel panel-default">
<div id="sidebarheading" class="panel-heading"><h5><b>Upcoming</b></h5></div>
<%= render 'goals/upcoming' %>
</div>
goals controller
def index
if params[:tag]
@goals = Goal.tagged_with(params[:tag])
else
@goals = Goal.all.order("deadline")
@accomplished_goals = current_user.goals.accomplished
@unaccomplished_goals = current_user.goals.unaccomplished
@top_3_goals = @unaccomplished_goals.top_3
end
end
goal model
class Goal < ActiveRecord::Base
belongs_to :user
acts_as_taggable
scope :accomplished, -> { where(accomplished: true) }
scope :unaccomplished, -> { where(accomplished: false) }
validates :name, presence: true
scope :top_3, -> do
order("deadline DESC").
limit(3)
end
end
Do I need to put anything in the sidebar_controller? I played around with adding logic there but it didn't seem to make any difference. I'm still a beginner so what I'm saying here may make no sense. Right now I have nothing in the sidebar_controller since the only view I have from there is _sidebar.html.erb
(I'm not quite sure how partials utilize controllers). The partial _upcoming.html.erb
worked perfectly if I rendered it in the goals index (the links all worked), but how can I get it to work if I render it in the _sidebar?
Thanks for putting up with me this far =]
回答1:
There shouldn't be such a thing as a sidebar controller, unless you plan to make the sidebar some sort of iframe or something ( which is strange ).
Like @patrickmcgraw suggested, I would create a before_action in the application controller to make sure that those variables are always set.
class ApplicationController < ActionController::Base
before_action :set_top_3_goals
def set_top_3_goals
@top_3_goals = current_user.goals.unaccomplished.top_3
end
end
来源:https://stackoverflow.com/questions/28787449/how-to-stop-nomethoderror-when-clicking-new-edit