7

Say I have a model User, which has a field of type json called settings. Let's assume that this field looks roughly like this:

{
  color: 'red', 
  language: 'English', 
  subitems: 
    {
      item1: true, 
      item2: 43, 
      item3: ['foo', 'bar', 'baz']
    }
}

If I do User.select(:settings) I will get all the settings for each user. But I want to get only the languages for a user. I tried both:

User.select("settings -> 'language'")

and

User.select("settings ->> 'language'")

but this just returns empty objects:

[#<User:0x007f381fa92208 id: nil>,
...]

Is this at all possible? If yes - can I do it using just json or do I need to switch to jsonb?

3
  • 3
    empty objects -- sure of that? Try doing .map(&:attributes) on the result. Commented Feb 10, 2016 at 11:38
  • You are right. attributes returns this {"id"=>nil, "?column?"=>"English"}. What confused me is the fact that normally the object would look like this when selecting a normal (not json) attribute: #<User:0x007f38200f3598 id: nil, name: "John">. However, apparently json selected data doesn't work like that. Commented Feb 10, 2016 at 11:59
  • 1
    It's just #to_s that's defined in a way that only outputs known columns. Custom columns from select are not known to be inside the table, so they're not printed out in #to_s, but are mapped regardless. Commented Feb 10, 2016 at 12:19

1 Answer 1

10

Try User.select("settings -> 'language' as user_language"). Each object in the resulting relation should respond to user_language.

Sign up to request clarification or add additional context in comments.

4 Comments

Cheers! Happy to help. BTW - it seems that without naming the selected value with a as user_language the result will still include the value but under a weird ?column? key.
Yes, I also saw the ?column? key.
in rails 6.1.3: column->'field' lead to the error Mysql2::Error: Invalid JSON path expression column->'$.field' allowed me to get the property

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.