【问题标题】:rails ams, Nested models undefined method `' for nil:NilClassrails ams,nil:NilClass 的嵌套模型未定义方法“”
【发布时间】:2017-01-02 04:58:56
【问题描述】:

我有以下型号:

class Appeal < ActiveRecord::Base
  belongs_to :applicant, :autosave => true
  belongs_to :appealer, :autosave => true
end

class Appealer < ActiveRecord::Base
  has_many :appeals, :autosave => true
end

class Applicant < ActiveRecord::Base
  has_many :appeals
end

我想要的是每个上诉人都持有他的最后上诉申请人的参考

所以我将 Appealer 模型修改为:

class Appealer < ActiveRecord::Base
  has_many :appeals, :autosave => true

  def last_applicant
    return self.appeals.last.applicant
  end
end

但我得到了错误:

undefined method `applicant' for nil:NilClass

奇怪的是,如果我调试这个(通过 RubyMine - Evaluate Expression)我可以得到申请人。

如果我试图获得最后的上诉:

class Appealer < ActiveRecord::Base
  has_many :appeals, :autosave => true

  def last_appeal
    return self.appeals.last
  end
end

一切正常。

我正在使用 active-model-serializer,尝试在序列化器中也这样做(我实际上在特定调用中需要这个值 - 不是整个模型),但它也没有出现相同的错误。

AMS 代码:

class AppealerTableSerializer < ActiveModel::Serializer
  attributes :id, :appealer_id, :first_name, :last_name, :city
  has_many :appeals, serializer: AppealMiniSerializer

  def city
    object.appeals.last.appealer.city
  end

end

我的问题: 如何在我的 JSON 中获取嵌套对象属性? 我做错了什么?

编辑: 我的控制器调用:

class AppealersController < ApplicationController
  def index
    appealers = Appealer.all
    render json: appealers, each_serializer: AppealerTableSerializer, include: 'appeal,applicant'
  end
end

我尝试过使用和不使用包含,仍然无法正常工作

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 serialization nested-attributes active-model-serializers


    【解决方案1】:

    也许我遗漏了一些东西,因为您的上诉人记录似乎还没有任何上诉。

    在这种情况下,这段代码

    def last_appeal
      return self.appeals.last
    end
    

    将返回 nil,这不会引发任何错误。但是如果你这样称呼它

    def last_applicant
      return self.appeals.last.applicant
    end
    

    return self.appeals.last 为 nil,您尝试在 nil 对象而不是 Appeal 对象上调用 applicant 方法。

    要修复它,只需添加对 nil 的检查

    class Appealer < ActiveRecord::Base
      has_many :appeals, :autosave => true
    
      def last_applicant
        last = self.appeals.last
    
        if last.nil?
          return nil
        else
          return last.applicant
        end
      end
    end
    

    【讨论】:

    • 它不是空的,正如我在问题中所写,我可以在 Evaluate Expression 中看到调试器中的值
    • @yossico 你能贴出调用序列化方法的代码吗?
    • 我已经添加了控制器调用
    • 你说对了 - 这是一张愚蠢的零支票,我想打自己的脸
    猜你喜欢
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    相关资源
    最近更新 更多