繁体   English   中英

ActiveRecord未定义方法“ has_key?” 对于nil:NilClass错误

[英]ActiveRecord undefined method `has_key?' for nil:NilClass error

我有一个相当简单的表格覆盖数据的Rails应用程序,它调用远程MySql 5.5 db。 使用Rails 3.2.21,Ruby 1.9.3。

应用程序中的页面之一引发以下错误:

NoMethodError in GvpController#input
   undefined method `has_key?' for nil:NilClass
   app/controllers/gvp_controller.rb:9:in `input'

这是来自控制器的有害代码:

class GvpController < ApplicationController
  def input
    # irrelevant stuff
    @list =  Vendor.gvp_vendor_names.map { |x| x.vendor_name }
    # more irrelevant stuff
  end      
  # other irrelevant methods
end

我假设对gvp_vendor_names的调用返回nil。

这是供应商模型类:

class Vendor < ActiveRecord::Base
  establish_connection :vendor_sql
  self.table_name = 'reporting_dw.vp_vendor_mapping'
  scope :gvp_vendor_names, -> {
    select('reporting_dw.vp_vendor_mapping.vendor_name')}
end

我搜索了此错误消息的其他帖子,到目前为止,还没有找到似乎相关的帖子。 我没有重写initialize方法(一种可能的原因),并且我认为语法是正确的(另一种)。

另外,我正在使用无业游民进行开发,所以我想也许我没有从无业游民框与数据库成功通信-可能是ssh或权限问题。 为了测试它,我在游民游箱上打开了一个ssh会话,通过命令行成功地与数据库连接,运行了一条select语句,瞧瞧,得到了我期望的结果的完整列表。 我也通过ssh在mysql workbench上尝试了它,没有问题。 因此,看来我可以与db进行远程通信,对其执行查询,拥有适当的权限等。

是否有人对问题可能有什么建议?

我假设您的数据库表上没有任何价值。 这就是为什么在您调用gvp_vendor_names映射值vendor_name期间控制器操作块中出现问题的原因

您应该通过检查对象值而不是访问firstclass来处理这种情况

GvpController < ApplicationController
  def input
    # irrelevant stuff
    @list =  Vendor.gvp_vendor_names.map { |x| x.vendor_name if x.present?}
    # more irrelevant stuff
  end      
  # other irrelevant methods
end

这样,您需要压缩nil值。 因此,如果要从控制器处理场景,请最终使用此命令:

class GvpController < ApplicationController
  def input
    # irrelevant stuff
    @list =  Vendor.gvp_vendor_names.map { |x| x.vendor_name if x.present?}.compact
    # more irrelevant stuff
  end      
  # other irrelevant methods
end

真正的问题可能只是我是Rails / ActiveRecord n00b。 经过更多的实验后,我发现以下更改更正了该错误。

在模型中,我添加了attr_accessible,然后使用了工程师mnky的建议,即使用方法而不是范围,如下所示:

class Vendor < ActiveRecord::Base
  establish_connection :vendor_sql 
  attr_accessible :vendor_name
  self.table_name = 'reporting_dw.vp_vendor_mapping'

  def self.gvp_vendor_names
    pluck(:vendor_name).sort
  end
end

然后在控制器中:

class GvpController < ApplicationController
  def input
    #irrelevant stuff
    @list = Vendor.gvp_vendor_names 
    #irrelevant stuff
  end
end

这样就解决了。 谢谢大家的建议!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM