62

How do you declare an array column in Rails?

Detail

I have the following model

rails generate model User address:text

but I want a model which can store multiple addresses per user. The following declaration gives me an error

rails generate model User address[]:text 

How do you declare an array column in Rails?

3
  • 1
    possible duplicate of Storing arrays in database : JSON vs. serialized array Commented Sep 5, 2015 at 8:59
  • This should probably be a apidock.com/rails/ActiveRecord/Associations/ClassMethods/…... Commented Sep 5, 2015 at 9:00
  • 3
    I need make a note about the answers that have default: [] on them. DON'T do this if you're adding a column to an existing table. You will lock your database down until the migration is finished running. You should instead add the column, populated it, then add the default. We need these three steps for hot compatibility. Commented Jul 20, 2021 at 17:55

4 Answers 4

111

You can use following steps

rails g migration add_subjects_to_book subjects:text

And the migration file:

class AddSubjectsToBook < ActiveRecord::Migration
  def change
    add_column :books, :subjects, :text, array: true, default: []
  end
end

We can check it now:

2.1.2 :001 > b = Book.create
   (0.2ms)  BEGIN
  SQL (2.0ms)  INSERT INTO "books" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2014-10-17 08:21:17.870437"], ["updated_at", "2014-10-17 08:21:17.870437"]]
   (0.5ms)  COMMIT
 => #<Book id: "39abef75-56af-4ad5-8065-6b4d58729ee0", title: nil, created_at: "2014-10-17 08:21:17", updated_at: "2014-10-17 08:21:17", description: {}, metadata: {}, subjects: []>

2.1.2 :002 > b.subjects.class
 => Array

If you want to add array while creating table you can do as follows

create_table :products do |t|
  t.string :name, null: false
  t.references :category, null: false
  t.text :tags, array: true, default: []
end

Note: array column is supported by PostgreSQL

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

1 Comment

This is postgresql specific
35

If you are using Postgres, then this post http://blog.plataformatec.com.br/2014/07/rails-4-and-postgresql-arrays/ suggests using array: true option in migration script:

create_table :users do |t|
  # other columns
  t.text :addresses, array: true, default: []
end

In case you are not using Postgres, this answer might be helpful: Storing arrays in database : JSON vs. serialized array

Comments

26

The examples using array: true would require Postgres or some other database capable of an arrays type. For MySQL, use generic serialization, which lets you store any arbitrary type in a column.

Database migration:

create_table :users do |t|
  t.text :addresses, default: [].to_yaml
  ...
end

Class with array attribute:

class User < ApplicationRecord
  serialize :addresses, Array
end

Using the attribute:

u = User.new
u.update_attributes addresses: ["123 Evergreen", "246 Main"]

The usual caveats apply to storing arrays in a database. It goes against the grain of relational databases to do this and will make it hard, slow, or impossible to do things like search for an individual item. However, it can be a fine solution for basic storage until you need to do those things.

Comments

6

If using Rails 5, follow the below steps to add an array of address in user table:

Run below command to generate a model with table,

rails generate model User address:text

The table will get create similar to the given below:

class CreateUser < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.text :address
      t.timestamps
    end
  end
end

Now add serialization for the address in a user model

class User < ApplicationRecord
 serialize :address, Array
end

Thank you.

1 Comment

This solution is specific for databases like SQLite not PostgreSQL or MySQL.

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.