Anton S.
Anton S.

Reputation: 1029

Loop JSON objects in Ruby On Rails

I am trying to figure out how to display custom HTML objects created by users. For example, the user can create custom styled button(s) with the following properties: color, font-size, and border-radius. Here is an example of my json:

    [
      {
        id: 2,
        configs: {
          color: "#000000",
          font_size: 10,
          border_radius: 0,
          display: true,
          button_1: [
            {
              color: "red",
              font_size: 12,
              border_radius: 4,
              display: true,
            }
          ],
        },
        created_at: "2020-05-07T21:42:04.808Z",
        updated_at: "2020-05-07T21:42:04.808Z",
      },
      {
        id: 3,
        configs: {
        color: "#000000",
        font_size: 10,
        border_radius: 0,
        display: true,
        button_1: [
          {
            color: "blue",
            font_size: 15,
            border_radius: 24,
          }
        ],
        button_2: [
          {
            color: "pink",
            border_radius: 2,
          }
        ],
      },
      created_at: "2020-05-07T22:29:31.255Z",
      updated_at: "2020-05-07T22:29:31.255Z",
    },
  ]

I want to display all buttons according to the user's style settings. Tried something like:

%p #{btn.id}: #{btn[:configs][:button_1][0][:color][:font_size]}

But it doesn't look practical. Besides, in certain cases it can lead to the error:

undefined method `[]' for nil:NilClass

I've tried to use gem like activerecord-typedstore but it seems like it doesn't support nested attributes (Is there a way to master a nested json with a json column?). Is there any way to display custom button(s) based on the user's criteria?

Upvotes: 1

Views: 337

Answers (1)

tadman
tadman

Reputation: 211730

In Ruby "configs" and :configs are not equivalent. You must use the type employed in the structure.

To navigate complex JSON structures use dig:

btn.dig('configs', 'button_1', 0, 'color', 'font_size')

You can also symbolize the keys if you want using symbolize_keys:

btn.symbolize_keys!

If you prefer symbols and you're reading in the JSON manually you can always request it with symbol keys out of the gate using the symbolize_names option to JSON.parse:

JSON.parse('{"test": true}')
# => {"test"=>true}
JSON.parse('{"test": true}', symbolize_names: true)
# => {:test=>true}

Upvotes: 2

Related Questions