Reputation: 953
I'm using a jsonb field in my Rails application and have installed the gem attr_json. Is there a way to receive the defined json_attributes programmatically? With a "normal" rails attribute, I would just do @instance.attribute_names. But with attr_json is there any way how to have the json_attributes returned?
class Vehicle < Item
include AttrJson::Record
attr_json :licence_plate, :string, container_attribute: "custom_attributes_indexed"
attr_json :brand, :string, container_attribute: "custom_attributes_indexed"
attr_json :serial_number, :string, container_attribute: "custom_attributes_indexed"
attr_json :inventory_number, :string, container_attribute: "custom_attributes_indexed"
end
For this code I would like to do something like @vehicle.json_attribute_names and have the following returned
["licence_plate", "brand", "serial_number", "inventory_number"]
Upvotes: 0
Views: 748
Reputation: 953
You can retrieve the defined json_attributes via: Vehicle.attr_json_registry.attribute_names
But even simpler to retrieve the attributes via the rails method attribute names
is to add rails_attribute: true
to your attr_json definitions. This will return all the "normal" attributes and the JSON attributes as an array.
[...]
attr_json :licence_plate, :string, container_attribute: "custom_attributes_indexed", rails_attribute: true
[...]
Upvotes: 1
Reputation: 6411
I have a Rails app that uses a JSONB column in Postgres and without any other gems I can call the following to get the keys...
Given a model Inspections
with a JSONB column called "results" I can do:
@some_inspection = Inspection.first
@some_inspection.results
#=> {"assigned_to" => "John Smith", "inspection_date" => "2020_01_02", "passed" => "true"}
@some_inspection.results.keys
#=> ["assigned_to", "inspection_date", "passed"]
I was under the impression that the great thing about having a JSONB column is that it seamlessly translates for me. I don't have any attr_json
nor any other specialized code in my model. Like so much Ruby and Rails "it just works". I pass it a hash and it stores that as JSON and when I ask for it, I get a hash. I can then do any hash methods like .values
or .keys
on it. If I need JSON back I can do @some_inspection.results.to_json
.
If you pass it actual JSON then it will just store the JSON text as a string in the column. You can then get the JSON back just by calling the column name like:
@some_inspection.results
#=> "{\"assigned_to\":\"John Smith\",\"inspection_date\":\"2020_01_02\",\"passed\":\"true\"}"
But if you want to do something like .keys
you have to parse it since it is a string:
JSON.parse(@some_inspection.results).keys
#=> ["assigned_to", "inspection_date", "passed"]
Upvotes: 0