2017-03-02 264 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

相關問題