PostgreSQL + JSONB + Ruby
Tags: postgres, ruby, beginners, tutorial
Published: 2023-04-04 15:54:26

## Introduction

PostgreSQL is an open source relational database management system that has gained immense popularity in recent years due to its powerful and flexible features. One such feature is the JSONB data type, which allows users to store and retrieve JSON data in a relational database. In this article, we will discuss how JSONB works in Postgres and how it can be used in conjunction with Rails.

## JSONB vs JSON

JSONB stands for "JSON Binary." It is a binary format for JSON data that is stored in a compressed format. This allows for faster data retrieval, as well as more efficient storage on disk. JSONB supports indexing, which means that it can be searched and filtered more quickly than JSON data. JSONB is also more flexible than JSON, allowing for greater precision when working with data types like numbers and dates.

JSON, on the other hand, stores JSON data as a text string. This makes it less efficient than JSONB, as it requires more disk space and takes longer to retrieve data. JSON does not support indexing, which means that it cannot be searched or filtered as quickly as JSONB.

In summary, if you need to store and query JSON data in PostgreSQL, JSONB is generally the better choice due to its speed and flexibility. However, if you don't need to search or filter the data and simply want to store it as a text string, then JSON may be sufficient.

## JSONB in PostgreSQL

JSONB stands for "JSON Binary," which is a binary representation of JSON data. It allows users to store, query, and index JSON data in a relational database, just like any other data type. JSONB is different from the standard JSON data type in that it stores data in a binary format, which makes it more efficient to store and query large JSON data sets.

JSONB is a powerful data type that allows users to store and query complex JSON data structures. It supports all standard JSON data types, such as strings, numbers, booleans, arrays, and objects. Additionally, it allows users to store and query nested JSON data structures, which can be useful for representing complex data sets.

## JSONB in Ruby On Rails

Rails provides a set of tools and conventions that make it easy to build web applications quickly and efficiently. Rails has built-in support for PostgreSQL, including support for the JSONB data type.

Rails allows users to store and retrieve JSONB data in a database using ActiveRecord, which is the ORM (Object-Relational Mapping) layer that Rails uses to interact with databases. ActiveRecord provides a set of methods for working with JSONB data, including methods for querying, updating, and creating JSONB data.

## Querying

To query JSONB data in Rails, we can use the where method on an ActiveRecord relation object. The where method takes a hash of key-value pairs that represent the conditions that we want to filter by.

For example, suppose we have a table named users that contains a column named metadata, which stores JSONB data representing user metadata. We can query this data using the following code:

```ruby
users = User.where("metadata ->> 'country' = ?", 'USA')
```

In this code, we are querying the users table and filtering by the value of the country key in the metadata JSONB data. We are using the ->> operator to extract the value of the country key as a string and comparing it to the string 'USA'.

We can also query nested JSONB data structures using the -> operator. For example, suppose we have a nested JSONB data structure representing a user's contact information:

```
metadata = {
  "name": "John Smith",
  "email": "john@example.com",
  "phone": {
    "home": "555-1234",
    "work": "555-5678"
  }
}
```

We can query the user's phone number using the following code:

```ruby
users = User.where("metadata -> 'phone' ->> 'home' = ?", '555-1234')
```

In this code, we are querying the users table and filtering by the value of the home key in the phone object within the metadata JSONB data.


## Update

To update JSONB data in Rails, we can use the update method on an ActiveRecord object. The update method takes a hash of key-value pairs that represent the changes that we want to make.

For example, suppose we want to update the metadata JSONB data for a user with an ID of 1. We can do this using the following code:

```ruby
user = User.find(1)
user.update(metadata: { "country": "Canada" })
```

In this code, we are finding the user with an ID of 1 using the find method and updating the metadata JSONB data to set the value of the country key to 'Canada' using the update method.

We can also update nested JSONB data structures using the -> operator. For example, suppose we want to update the user's phone number:

```ruby
user.update("metadata -> 'phone' ->> 'home'" => '555-4321')
```

In this code, we are updating the value of the home key in the phone object within the metadata JSONB data to '555-4321' using the update method.

## Create

To create JSONB data in Rails, we can use the create method on an ActiveRecord model. The create method takes a hash of key-value pairs that represent the data that we want to create.

For example, suppose we want to create a new user with metadata representing their country and phone number:

```ruby
user = User.create(metadata: { "country": "USA", "phone": { "home": "555-1234" } })
```

In this code, we are creating a new user with metadata that includes a country key with a value of 'USA' and a phone object with a home key and a value of '555-1234'.

## Conclusion

JSONB is a powerful data type that allows users to store and query JSON data in a relational database. It is supported in PostgreSQL and can be used in conjunction with Rails to build powerful web applications. In this article, we discussed how to query, update, and create JSONB data in Rails using ActiveRecord. We also provided examples of querying nested JSONB data structures and updating nested JSONB data structures. By using JSONB in conjunction with Rails, users can build powerful and flexible web applications that can handle complex data structures with ease.