0

Мне сложно понять, как включить логику нескольких контроллеров в боковую панель.Как остановить NoMethodError при нажатии #new & #edit?

Например, я хочу иметь секцию на боковой панели, которая использует логику @habits из habits_controller и раздел, который использует логику @unaccomplished_goals с помощью функции goal_controller.

Для этого вопроса давайте просто сосредоточимся на @unaccomplished_goals.

<% @top_3_goals.each do |goal| %> правильно показывает в боковой панели приложения, который является производным от goals_controller #index @top_3_goals = @unaccomplished_goals.top_3НО если я нажимаю на ссылки goals/new или goals/1/edit я получаю страшился: undefined method each for nil:NilClass!

Вот расстройство зрения:

Я использую <%= render 'sidebar/sidebar' %> в views/layouts/application.html.erb , чтобы захватить views/sidebar/_sidebar.html.erb, чтобы использовать <%= render 'goals/upcoming' %> захватить views/goals/_upcoming.html.erb

мнения/цели/_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>

просмотров/боковой панели/_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>

цели контроллер

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

цель модели

class Goal < ActiveRecord::Base 
 
\t belongs_to :user 
 
\t acts_as_taggable 
 
\t scope :accomplished, -> { where(accomplished: true) } 
 
\t scope :unaccomplished, -> { where(accomplished: false) } 
 
\t validates :name, presence: true 
 

 
\t scope :top_3, -> do 
 
    order("deadline DESC"). 
 
    limit(3) 
 
end 
 
end

мне нужно положить что-нибудь в sidebar_controller ли? Я играл с добавлением логики, но, похоже, это не имело никакого значения. Я все еще новичок, поэтому то, что я говорю здесь, не имеет смысла. Прямо сейчас у меня нет ничего в sidebar_controller, поскольку у меня есть только один вид _sidebar.html.erb (я не совсем уверен, как частичные используют контроллеры). Частичный _upcoming.html.erb работал отлично, если я отобразил его в индексе целей (все ссылки были обработаны), но как я могу заставить его работать, если я его отрисую в _sidebar?

Спасибо за расклеивание со мной этого далеко =]

+2

Если боковая панель присутствует на всех страницах, то вам необходимо либо добавить код на каждый запрос (через контроллер приложения), заполняющую все '@' переменных, используемых видом на боковой панели или видом на боковой панели должны делать отдельные запросы на сервер через ajax. При каждом запросе активен только один контроллер. – patrickmcgraw

+1

Я думаю, что часть проблемы может быть некоторой путаницей вокруг методов контроллера (или «действий»). Запрос, скажем, GET на «цели/новый», будет проанализирован механизмом маршрутизации и направлен на одно действие контроллера. Весь код, необходимый для отображения для этого представления, должен быть включен в это одно действие. Надеюсь, это поможет. – messanjah

ответ

1

Там не должно быть такой вещи, как контроллер боковой панели, если вы не планируете сделать врезку какой-то встроенный или что-то (что странно).

Как и @patrickmcgraw, я хотел бы создать before_action в контроллере приложения, чтобы убедиться, что эти переменные всегда установлены.

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 
Смежные вопросы