我有一个相当简单的数据形式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方法(一个可能的原因),我认为语法是正确的(另一个)。
作为一个额外的皱纹,我正在使用vagrant进行开发,所以我想也许我没有成功地与流氓盒中的数据库进行通信 - 可能是ssh或权限问题。为了测试它,我在vagrant box上打开了一个ssh会话,通过命令行与db成功连接运行了一个select语句,然后看看,得到我期望的完整结果列表。我也通过ssh尝试使用mysql workbench,没有任何问题。所以,似乎我可以与数据库远程通信,对它执行查询,拥有适当的权限等。
有没有人对这个问题有什么建议?
答案 0 :(得分:2)
我假设您的数据库表没有任何价值。这就是您在调用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
答案 1 :(得分:0)
真正的问题可能只是我是Rails / ActiveRecord n00b。经过一些实验,我发现以下更改纠正了错误。
在模型中我添加了attr_accessible,然后使用了engineermnky建议使用方法而不是范围,如下所示:
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
修复了它。谢谢大家的建议!