【问题标题】:ActionView::Template::Error (undefined method `each' for nil:NilClass):ActionView::Template::Error(nil:NilClass 的未定义方法“每个”):
【发布时间】:2012-08-22 17:31:37
【问题描述】:

我在本地没有遇到错误,但在 Heroku 上。错误是:

'ActionView::Template::Error (nil:NilClass 的未定义方法`each')'

'each' 指的是下面我的 User callback.html.erb 视图的 行中 @position 中的每个 i:

<% for i in @positions %>
<strong>
<% begin %>
<%= @user.positions.find_by_id(i).title + " at " %>
<% rescue %>
<% end %>

<% begin %>
<%= @user.positions.find_by_id(i).company %>
<% rescue %>
<% end %>
</strong>

这是我的身份验证控制器的相关部分(回调部分)

def callback

...

    @user = current_user

...

    #positions
    for i in 0..(positions.count-1)

      begin
        @company_i = companies[i]['name']
      rescue
      end

      begin
        @title_i = positions[i]['title']
      rescue
      end

      begin
        @industry_i = companies[i]['industry']
      rescue
      end

      begin
        @start_month_i = positions[i]['start-date']['month']
        @start_year_i = positions[i]['start-date']['year']
      rescue
      end

      begin
        @end_month_i = positions[i]['end-date']['month']
        @end_year_i = positions[i]['end-date']['year']
      rescue
      end

      begin
        @li_pos_id_i = positions[i]['id']
      rescue
      end

      if Position.find_by_li_pos_id(@li_pos_id_i).nil?
        @user.positions.build(li_pos_id: @li_pos_id_i, company: @company_i, title: @title_i, 
          industry: @industry_i, start_month: @start_month_i, start_year: @start_year_i, 
          end_month: @end_month_i, end_year: @end_year_i)
      end
    end

    @user.save
    @positions = @user.positions.map(&:id)
end

我认为这与我的 .find_by 方法返回 nil 值有关,但我不确定如何解决它。谢谢!

编辑的授权控制器:

positions.each do |position|
      begin
        @li_pos_id = position.id
        @title = position.title
        @company = position.company.name
        @industry = position.company.industry
        @start_month = position.start_date.month
        @start_year = position.start_date.year
        @end_month = position.end_date.month
        @end_year = position.end_date.year
      rescue
      end

      unless Position.find_by_li_pos_id(@li_pos_id)
        current_user.positions.build(li_pos_id: @li_pos_id, title: @title, company: @company, industry: @industry, 
          start_month: @start_month, start_year: @start_year, end_month: @end_month, end_year: @end_year)
      end

      @user.save
      @user.positions.save
    end

【问题讨论】:

  • 您确定当前用户在生产中创建了职位吗?该关联中可能没有任何对象
  • map 在这种情况下会返回一个空数组。
  • @tadman 这绝对是丑陋的,感谢您的意见。我已经修改它并粘贴在上面的编辑中。问题是位置模型数据(用户 has_many 位置)没有保存到 heroku 数据库。任何想法为什么?我的用户数据保存得很好

标签: ruby-on-rails heroku


【解决方案1】:

您在这里所做的称为“Pokemon 异常处理”,因为您会捕获所有异常并将它们扔到垃圾箱中。如果您与其他开发人员一起工作,这是一个非常糟糕的习惯,并且会导致大量的挫败感,因为它隐藏了意外错误并使调试变得更加困难,因为在这些部分中您将永远无法获得正确的堆栈跟踪已经被围起来了。

您不应盲目地捕获异常,而应该在适用的情况下捕获特定的、预期的异常,并且只在可能引发它们的地方捕获。您还应该尽一切努力避免一开始就生成它们。

这方面的一个例子是:

<% @position_ids.present? and @position_ids.each do |position_id| %>

调用位置变量i 的风格也很差,因为这种名称通常保留用于增量或索引,仅此而已。使用稍长但更具描述性的名称会带来不可估量的帮助。

您还在循环中使用这种非常奇特的for x in y 表示法,Ruby 鼓励使用更简洁的y.each do |x| 版本。

此外,测试nil? 而不仅仅是测试对象本身几乎总是多余的并且可以被消除。 nil? 测试仅在您想要区分 falsenil 时相关,这两个值是 Ruby 中仅有的两个非真值。在这种情况下,简单的unless (x)if (x.nil?) 更好。

至于为什么你在@positions 中没有得到任何东西,这可能是因为callback 例程首先没有运行。从表面上看,除非其中某处有return,否则必须在例程结束时分配该值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多