Controller无法将实例变量传递到视图中

时间:2017-01-10 11:37:41

标签: ruby-on-rails model-view-controller instance-variables

在我的主页中,我遍历对象集合,对于每个对象,我在表格行中呈现其属性。有四个对象集合,在我的控制器中定义为实例变量,都使Guard(根据使用的方法)引发以下错误之一:

ActionView::Template::Error: undefined method `each_with_index' for nil:NilClass
ActionView::Template::Error: undefined method `any?' for nil:NilClass

我的应用程序视图中引发上述错误的代码是:

<table class="col-md-4 col-md-offset-1">
  <thead>
    <tr>
      <th> Rank </th>
      <th> Gamer </th>
      <th> Points </th>
    </tr>
 </thead>
 <tbody>
   <% @atp_gamers.each_with_index do |gamer, index| %>
     <tr>
       <td class="index"> <%= index+1 %> </td>
       <td class="gamer"> <%= gamer.name %> </td>
       <td class="atppoints"> <%= gamer.atpscore %> </td>
     </tr>
   <% end %>
     <tr class="current-user">
       <td> <%= @atp_gamers.to_a.index(current_user) + 1 %> </td>
       <td> <%= current_user.name %> </td>
       <td> <%= current_user.atpscore %> </td>
     </tr>
   </tbody>
</table>
<table class="col-md-4 col-md-offset-2">
  <thead>
    <tr>
      <th> Year </th>
      <th> Champion </th>
      <th> Points </th>
    </tr>
  </thead>
  <tbody>
    <% if @atp_champions.any? %>
      <% @atp_champions.each do |champion| %>
        <tr>
          <td class="year"> <%= champion.created_at.year %> </td>
          <td class="winnername"> <%= champion.name %> </td>
          <td class="winnerpoints"> <%= champion.points %> </td>
        </tr>
      <% end %>
    <% end %>
  </tbody>
</table>

上面的代码是在原始主页中呈现的部分(名为_gamers_home.html.erb)的一部分:

<% if logged_in? %>
  <% if current_user.gamer? %>
    <%= render 'static_pages/gamers_home' %>
  <% else %>
    <%= render 'static_pages/non_gamers_home' %>
  <% end %>
<% else %>
  <%= render 'static_pages/non_logged_in_home' %>
<% end %>

logged_in?方法定义为!current_user.nil?

产生nil的实例变量是:@atp_gamers@wta_gamers@atp_champions@wta_champions,在控制器中定义如下:

  def home
    if logged_in? && !current_user.gamer?
      ...l
    elsif logged_in? && current_user.gamer?
      @gamers = User.where(gamer: true)
      @atp_gamers = @gamers.order(atpscore: :desc).limit(50)
      @wta_gamers = @gamers.order(wtascore: :desc).limit(50)
      @atp_champions = AtpChampion.all
      @wta_champions = WtaChampion.all
      ...
    end
  end

引发错误的第一个实例变量(each_with_index' for nil:NilClass)是@atp_gamers。在视图中,我尝试使用其显式值(即User.where(gamer: true).order(atpscore: :desc).limit(50))更改它,并接受相应的代码。在此更改之后,Guard会为@atp_champions引发错误。

使用rails控制台@atp_gamers@wta_gamers不为空,返回100个用户中的50条记录。 @atp_champions@wta_champions不是nil,而是空数组。

我怀疑这可能只是由Guard引发的问题,因为rails服务器成功呈现了视图。

1 个答案:

答案 0 :(得分:0)

def home
  if logged_in?  # delete this line
  ...
  end  # delete this line
end

删除if logged_in?,看看会发生什么。

也许您必须在控制器中使用before_action :logged_in_user, only :home并将logged_in_user方法定义为私有方法。

如果还允许非登录用户访问home操作,则需要在视图中使用if语句erb。像,

<% if logged_in? %>
  <% @atp_gamers.each_with_index do |gamer, index| %>
  ...
<% end %>

- UPDATE -

也许,它需要将变量抛给部分。

替换

<%= render 'static_pages/gamers_home' %>

<%= render partial: 'static_pages/gamers_home', locals: {atg_gamers: @atp_gamers, wta_gamers: @wta_gamers, atp_champions: @atp_champions, wta_champions, @wta_champions} %>

并将部分中的@atp_gamers@wta_gamers@atp_champions@wta_champions替换为atp_gamerswta_gamers,{{1} },atp_champions

尝试看看会发生什么。