16
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails + PostgreSQLでArray型を使う

Last updated at Posted at 2020-12-09

こんにちは。

この記事では、Rails + PostgreSQL で Array型のカラムを使用する方法を紹介します。
「Array型を使わずにテーブル分けろ」ってツッコミはしないでください。

array型ってどういうの?

端的にいうと、

1つのカラムに複数の値を格納できるデータ型

です。

例えば、librariesテーブルにbooksカラムというArray型のカラムを作成した場合、
「こころ」、「源氏物語」という複数の値を1つのカラムに保存することができます。

実際にデータを作ると以下のようになります。

postgres=# INSERT INTO libraries VALUES('books', ARRAY['こころ', '源氏物語']);
INSERT 0 1

postgres=# SELECT * FROM libraries ;
   name   | books
----------+---------
 東京図書館 | {こころ,源氏物語}

Railsで使う方法

1. migration

array型にするカラムに array: true オプションを付与します。

class CreateLibraries < ActiveRecord::Migration[6.0]
  def change
    create_table :libraries do |t|
      t.string :name
      t.string :books, array: true, default: []

      t.timestamps
    end
  end
end

2. Create

保存する値を配列で渡します。

Library.create(name: "東京図書館", books: ["こころ", "源氏物語"])

3. Show

カラムを参照すると、配列で値が返ってきます。

library = Library.find_by(name: "東京図書館")
library.books
=> ["こころ", "源氏物語"]

4. Query

調べてみると、Array型の検索が高機能だったので、ユースケースごとに紹介します。

ユースケースとしては以下の4つがあるとします。

  • 「こころ」を蔵書した図書館を探したい
  • 「こころ」と「源氏物語」の両方を蔵書した図書館を探したい
  • 「こころ」と「源氏物語」のどちらかを蔵書した図書館を探したい
  • 2冊以上の本を蔵書している図書館を探したい

順番に確認していきます。

「こころ」を蔵書した図書館を探したい

= を使用します。

Library.where("'こころ' = ANY (books)")

「こころ」と「源氏物語」の両方を蔵書した図書館を探したい

@> を使用します。

Library.where('books @> ARRAY[?]::varchar[]', ['こころ', '源氏物語'])

「こころ」と「源氏物語」のどちらかを蔵書した図書館を探したい

&& を使用します。

Library.where('books && ARRAY[?]::varchar[]', ['こころ', '源氏物語'])

2冊以上の本を蔵書している図書館を探したい

array_length を使用します。

Library.where("array_length(books, 1) >= 2")

まとめ

いかがでしたでしょうか。
Array型を使用すれば、手軽に複数の値を1つのカラムに格納することができ、様々なユースケースに対応した検索をすることができます。
どうしても「1つのテーブルでまとめたい」という時はArray型を是非検討してみてください。

参考

16
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?