as_json和动态方法的使用

Xer*_*ero 0 ruby ruby-on-rails

我有一个简单的课程(没有 Rails)

class Tax

  attr_reader :guest_age

  def initialize(guest_age)
    @guest_age = guest_age
  end

  def amount
    0
  end

end
Run Code Online (Sandbox Code Playgroud)

该对象有一个“金额”自定义方法,我希望在执行此操作时将金额结果包含在 json 中:tax.as_json(methods: :amount)

但这不起作用,这仅返回带有变量的对象。

我现在得到的:

{“guest_age”:18}

我期待的是:

{ “guest_age”:18,“金额”:0 }

请参阅https://apidock.com/rails/ActiveModel/Serializers/JSON/as_json

笔记 :

我想保留这个对象而不依赖于活动记录库。

Mar*_*iej 5

使用 Rails 5.2.2 进行测试,这是以下来源as_json

def as_json(options = nil) #:nodoc:
  if respond_to?(:to_hash)
    to_hash.as_json(options)
  else
    instance_values.as_json(options)
  end
end
Run Code Online (Sandbox Code Playgroud)

这意味着如果您to_hash在类中实现一个方法,您的as_json调用将按照您希望的方式工作:

class Tax

  attr_reader :guest_age

  def initialize(guest_age)
    @guest_age = guest_age
  end

  def amount
    0
  end

  def to_hash
    instance_values.merge(amount: amount)
  end
end
Run Code Online (Sandbox Code Playgroud)

和...

Tax.new(1).as_json
# => {"guest_age"=>1, "amount"=>0}
Run Code Online (Sandbox Code Playgroud)

这将包括amount始终,但似乎没有一个简单的方法可以解决这个问题。

但它的工作方式可能有所不同,您需要明确丢弃amount

Tax.new(1).as_json(except: :amount)
# => {"guest_age"=>1}
Run Code Online (Sandbox Code Playgroud)

或者明确指定您希望序列化的属性:

Tax.new(1).as_json(only: "guest_age")
# => {"guest_age"=>1}
Run Code Online (Sandbox Code Playgroud)

methods您想要使用的选项似乎与 ActiveRecord 严格相关。