fydelio
fydelio

Reputation: 953

JsonB and attr_json gem: Get the defined attributes programmatically

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

Answers (2)

fydelio
fydelio

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

Beartech
Beartech

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

Related Questions