0

I'm on Ruby On Rails 7 I have a class ActiveRecord class called Thread.

There are 2 records :

 id: 1,
 subject: "Hello",
 participants:
  [{"name"=>"guillaume", "email"=>"[email protected]"},
   {"name"=>"Fabien", "email"=>"[email protected]"},]

id: 2,
 subject: "World",
 participants:
  [{"name"=>"guillaume", "email"=>"[email protected]"},
   {"name"=>"hakim", "email"=>"[email protected]"},]

participants is a JSONB array column I want to find records who have the email "[email protected]" in participants column.

3

1 Answer 1

1

I don't think this is supported directly by AR.

You can "unwrap" the jsonb array using _jsonb_array_elements" or as the docs say: "Expands the top-level JSON array into a set of JSON values."

See https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE

You can query the DB with SQL like this:

select * from threads
where exists(
    select true 
    from jsonb_array_elements(participants) as users 
    where users->>'email' = '[email protected]'
)

Which translates into something like this in AR

condition = <<~SQL
  exists(
    select true 
    from jsonb_array_elements(participants) as users
    where users->>'email' = ?
  )
SQL

Thread.where(condition, '[email protected]')

(from the top of my head. can not test this)

IMHO: This is something that I see often happening with JSONB data: looks nice and simple in the beginning and then turns out to be more complicated (to query, validate, enforce integrity, insert) than a proper relationship (e.g. a participants table that links users/threads)

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

1 Comment

You're absolutely right on the last point - the unnessicary use of JSON/JSONB is a known anti-pattern.

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.