在我的视图中循环访问变量的问题

时间:2013-09-04 18:48:46

标签: ruby-on-rails loops views

我是Ruby / Rails的新手,我有一个奇怪的问题,我似乎无法理解我究竟做错了什么。

我在视图中有以下代码

<% gameNum = 0 %>
gameNum: <%= gameNum %>
homeTeamIndex: <%= @games[gameNum].homeTeamIndex %>
awayTeamIndex: <%= @games[gameNum].awayTeamIndex %><br />
<%= @NflTeams[@games[gameNum].homeTeamIndex].name %>
<%= @NflTeams[@games[gameNum].awayTeamIndex].name %><br />
<% gameNum = 1 %>
gameNum: <%= gameNum %> 
homeTeamIndex: <%= @games[gameNum].homeTeamIndex %>
awayTeamIndex: <%= @games[gameNum].awayTeamIndex %><br />
<%= @NflTeams[@games[gameNum].homeTeamIndex].name %>
<%= @NflTeams[@games[gameNum].awayTeamIndex].name %><br />

<% (0..@games.count).each do |gameNum| %>
  gameNum: <%= gameNum %>
  homeTeamIndex: <%#= @games[gameNum].homeTeamIndex %>
  awayTeamIndex: <%#= @games[gameNum].awayTeamIndex %> <br />
  <%#= @NflTeams[@games[gameNum].homeTeamIndex].name %>
  <%#= @NflTeams[@games[gameNum].awayTeamIndex].name %>
<% end %>

当我查看我的观点时,我得到以下结果:

gameNum: 0 homeTeamIndex: 10 awayTeamIndex: 3
Detroit Lions Buffalo Bills
gameNum: 1 homeTeamIndex:  awayTeamIndex: 
Cinncinatti Bengals Cleveland Browns
gameNum: 0 homeTeamIndex:  awayTeamIndex: 
homeTeamIndex: awayTeamIndex:
gameNum: 1 homeTeamIndex:  awayTeamIndex: 
homeTeamIndex: awayTeamIndex:
gameNum: 2 homeTeamIndex:  awayTeamIndex: 
homeTeamIndex: awayTeamIndex:
gameNum: 3 homeTeamIndex:  awayTeamIndex: 
homeTeamIndex: awayTeamIndex:
gameNum: 4 homeTeamIndex:  awayTeamIndex: 

但是,如果我取消注释任何一行:

homeTeamIndex: <%#= @games[gameNum].homeTeamIndex %>
awayTeamIndex: <%#= @games[gameNum].awayTeamIndex %> <br />
<%#= @NflTeams[@games[gameNum].homeTeamIndex].name %>
<%#= @NflTeams[@games[gameNum].awayTeamIndex].name %>

我收到以下错误(方法名称根据我取消注释的行更改):

undefined method `homeTeamIndex' for nil:NilClass

我真的不明白循环中发生的事情使实例变量不可用。

我希望有人可以告诉我,我做错了什么,因为在一个视图中这看起来很简单,我无法让它发挥作用。

更新

根据德米特里的建议,我改变了我的观点:

<% gameNum = 0 %>
<% (@games).each do |game| %>
  <strong>Game <%= gameNum+1 %>  </strong> <br />
  <%= image_tag(@NflTeams[game.homeTeamIndex].imagePath,
                size: "40") %>
  <%= @NflTeams[game.homeTeamIndex].name %>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VS
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <%= image_tag(@NflTeams[game.awayTeamIndex].imagePath,
                size: "40") %>
  <%= @NflTeams[game.awayTeamIndex].name %> <br />
  <% gameNum += 1 %>
<% end %>

模型如下:

NflTeams

class CreateNflTeams < ActiveRecord::Migration
  def change
    create_table :nfl_teams do |t|
      t.string :name
      t.string :imagePath

      t.timestamps
    end
  end
end

游戏

class CreateGames < ActiveRecord::Migration
  def change
    create_table :games do |t|
      t.integer :homeTeamIndex
      t.integer :awayTeamIndex
      t.integer :spread
      t.integer :week_id

      t.timestamps
    end
  end
end

awayTeamIndex和homTeamIndex是NflTeams模型的索引,因此我可以轻松地拉出Name和ImagePath。

我仍然在线上获取未定义的方法:

<%= image_tag(@NflTeams[game.homeTeamIndex].imagePath,
              size: "40") %>

还有其他建议吗?

更新2

我只包括迁移,因为这两个模型的模型中没有太多。 但就是这样。

class NflTeam < ActiveRecord::Base
end

class Game < ActiveRecord::Base

  belongs_to :week

  validates :homeTeamIndex, :inclusion => { :in => 0..100 }
  validates :awayTeamIndex, :inclusion => { :in => 0..100 }
end

这是控制器代码:

class WeeksController < ApplicationController
  before_action :signed_in_user
  before_action :confirmed_user

  ...

  def show
    @week = Week.find(params[:id])
    @games = @week.games
    @NflTeams = NflTeam.all
  end

  ...

end

1 个答案:

答案 0 :(得分:0)

您没有正确访问循环中的@games。看起来你正在考虑这行中的gameNum:

<% (0..@games.count).each do |gameNum| %>  

好像它是一个数字索引并使用它来访问集合中的对象,如下所示:

homeTeamIndex: <%#= @games[gameNum].homeTeamIndex %>

这是错误的,因为“gameNum”实际上是魔法红宝石为你提供的@games集合中的对象,所以你需要的是这样的:

<% (@games).each do |game| %>
  gameNum: <%= game.number %>
  homeTeamIndex: <%= game.homeTeamIndex %>
  awayTeamIndex: <%= game.awayTeamIndex %> <br />
  <%= game.homeTeam.name %>
  <%= game.awayTeam.name %>
<% end %>

希望这会有所帮助:)

P.S。
这个解决方案取决于你的模型当然是如何设置的,如果你可以证明它可能会让你的问题更清楚,让别人解释。


编辑 - 完整解决方案

我将向您展示如何在您的解决方案中呈现信息的和平。

要开始一个小建议,您在评论中提到

  

将其更改为仅查询表单中的数据库   homeTeamIndex和awayTeamIndex

虽然这可能有效,但在视图中放置此类例程是一种不好的做法,最好定义一个方法来在助手中完成这样的例程并在视图中调用它。

现在,解决方案......

首先,您需要正确定义模型关联,这些关联仅根据您共享的代码进行部分定义。你需要的是:

告诉所有与他们相关的课程(他们是这样的):
我会在团队中放弃'Nfl',因为它会让课程命名混乱

class Week < ActiveRecord::Base
  has_many :games
end

class Game < ActiveRecord::Base
  belongs_to :week
  belongs_to :home_team, class_name: "Team", foreign_key: :home_team_id
  belongs_to :away_team, class_name: "Team", foreign_key: :away_team_id
end

class Team < ActiveRecord::Base
  has_many :home_games, class_name: "Game", foreign_key: :home_team_id
  has_many :away_games, class_name: "Game", foreign_key: :away_team_id
end

注意:请查看Active Record Associations,以便更深入地了解这些内容。


编辑

更正上面的模型关联并进行测试以确保它们正常工作:)

确保您拥有以下数据库架构来备份关联...

  create_table "games", force: true do |t|
    t.integer  "game_number"
    t.integer  "week_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "home_team_id"
    t.integer  "away_team_id"
  end

  create_table "teams", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "weeks", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

编辑 请注意,在rails中创建模型时,默认情况下所有表都包含id字段


通过这些协会,您现在可以像以前一样在控制器中获得一周:

class WeeksController < ApplicationController

  ...

  def show
    @week = Week.find(params[:id])
    @games = @week.games
  end

  ...

end

最后构建你的观点:
在WeeksController中#show
/views/weeks/show.html.erb

<% if @games.any? %>
  <% render @games %>
<% end %>

这一行“render @games”将搜索'/views/games/_game.html.erb'并为该集合中的每个游戏呈现它@games

* / views / games / _game.html.erb - 局部视图*

<strong> Game <%= game.game_number %>  </strong> <br />
<%= image_tag(game.home_team.imagePath, size: "40") %>
<%= game.home_team.name %>

  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VS
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<%= image_tag(game.away_team.imagePath, size: "40") %>
<%= game.away_team.name %> <br />

就是这样,唯一令人费解的是让模特协会怀疑并不太困难。