Rails 5:attr_accessor抛出NoMethodError(未定义的方法'keys'为nil:NilClass):
问题描述:
我在模型中有2个非数据库属性。如果其中一人有一个值,我需要返回对方一JSON响应:Rails 5:attr_accessor抛出NoMethodError(未定义的方法'keys'为nil:NilClass):
class Car < ApplicationRecord
attr_accessor :max_speed_on_track
attr_accessor :track
def attributes
if !self.track.nil?
super.merge('max_speed_on_track' => self.max_speed_on_track)
end
end
end
的问题是该行“如果self.track.nil!?”当控制器试图返回json时抛出一个错误
也许有更好的方法,因为我读到使用attr_accessor是一种代码异味。
我想要做的是如果用户通过我一个跟踪值作为查询参数,然后我将该值传递给模型,它使用它来计算max_speed_on_track
,并返回该值。
显然,如果没有用户提供的轨道,那么我不想在json中返回max_speed_on_track
。
控制器方法现在是非常基本的(我仍然需要添加检查跟踪参数的代码)。该代码会在保存行中引发错误。
def create
@car = Car.new(car_params)
if @car.save
render json: @car, status: :created
else
render json: @car.errors, status: :unprocessable_entity
end
end
答
尝试了这一点:
class Car < ApplicationRecord
attr_accessor :max_speed_on_track
attr_accessor :track
def as_json(options = {})
if track.present?
options.merge!(include: [:max_speed_on_track])
end
super(options)
end
end
由于Rails使用attributes
方法,而你只需要这对JSON输出,可以覆盖as_json
方法就像在this article。当track
存在(而不是零)时,这将允许你在你的json输出中包含你的max_speed_on_track
方法。
+0
谢谢,这个工作...但现在我开始看到这里的局限性,我想应该转移到RABL模板或ActiveModelSerialiazers。 – rmcsharry
如果这仅用于调用'to_json'时,为什么不重写'as_json'方法而不是'attributes'方法?另外,不用'if!self.track.nil?',你可以使用'if track.present?'。它读起来更容易。 – jeremywoertink
谢谢,但如果self.track.present?抛出相同的错误 – rmcsharry
我读了这个http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/关于as_json,但我仍然坚持。我在as_json方法中加入了什么,以便在track不为null时包含我想要的字段,但在track有值时将其排除。 – rmcsharry