I have an simple class (without Rails)
class Tax
attr_reader :guest_age
def initialize(guest_age)
@guest_age = guest_age
end
def amount
0
end
end
This object has an "amount" custom method and I want to include the amount result in the json when I do this : tax.as_json(methods: :amount)
But this is not working, this return only the object with variables.
What I'm getting now :
{ "guest_age": 18 }
What I am expecting is :
{ "guest_age": 18, "amount": 0 }
See https://apidock.com/rails/ActiveModel/Serializers/JSON/as_json
Note :
I want to keep this object without active record library dependency.
Tested with Rails 5.2.2, this is the source of 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
Which means that if you implement a to_hash
method in your class, your as_json
call will work the way you wish:
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
And...
Tax.new(1).as_json
# => {"guest_age"=>1, "amount"=>0}
This will include the amount
always though, there does not seem to be an easy way around that.
It can work differently though, you need to explicitly throw away the amount
:
Tax.new(1).as_json(except: :amount)
# => {"guest_age"=>1}
Or explicitly specify the attributes you wish to be serialized:
Tax.new(1).as_json(only: "guest_age")
# => {"guest_age"=>1}
The methods
option that you'd like to use seems to be strictly tied to ActiveRecord.
Can you define a custom method in your class?
def to_h
{guest_age: @guest_age, amount: amount}
end
So you can call:
tax = Tax.new(18)
p tax.to_h
#=> {:guest_age=>18, :amount=>0}
Or
require 'json'
puts tax.to_h.to_json
#=> {"guest_age":18,"amount":0}
the method option works for active model object.
class Tax
include ActiveModel::Serialization
include ActiveModel::Serializers::JSON
attr_accessor :guest_age
def initialize(guest_age)
@guest_age = guest_age
end
def attributes
{'guest_age' => nil}
end
def amount
0
end
end
code like this should work, for more info see the source code.
https://github.com/rails/rails/blob/master/activemodel/lib/active_model/serialization.rb
https://github.com/rails/rails/blob/master/activemodel/lib/active_model/serializers/json.rb
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.