2017-03-02 179 views
0

我在模型中有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 
+1

如果这仅用于调用'to_json'时,为什么不重写'as_json'方法而不是'attributes'方法?另外,不用'if!self.track.nil?',你可以使用'if track.present?'。它读起来更容易。 – jeremywoertink

+0

谢谢,但如果self.track.present?抛出相同的错误 – rmcsharry

+0

我读了这个http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/关于as_json,但我仍然坚持。我在as_json方法中加入了什么,以便在track不为null时包含我想要的字段,但在track有值时将其排除。 – rmcsharry

回答

1

尝试了这一点:

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

相关问题