Rails: добавление миграции для добавления массива (по умолчанию пуст)

Я пытаюсь добавить столбец с именем share в один из моих ресурсов. Идея заключается в том, что пользователи могут загружать документы и делиться ими с другими (конкретными) пользователями, а массив содержит электронные письма тех, с которыми пользователь хочет поделиться.

Я попытался добавить миграцию с кодом

class AddShareToDocuments < ActiveRecord::Migration
  def change
    add_column :documents, :share, :array, :default => []
  end
end

Но когда я открываю консоль рельсов в командной строке, он говорит, что share: nil и user.document.share.class - это NilClass.

Создание нового массива в изолированной программной консоли rails путем ввода

newarray = []

говорит, что newarray.class - это Array.

Может ли кто-нибудь определить, что я делаю неправильно?

Ответ 1

Rails 4 тип данных PostgreSQL Array

В терминале

$ rails generate migration AddTagsToProduct tags:string

Файл миграции:

class AddTagsToProduct < ActiveRecord::Migration
  def change
    add_column :products, :tags, :string, array: true, default: []
  end
end

https://coderwall.com/p/sud9ja/rails-4-the-postgresql-array-data-type

Ответ 2

если вы хотите поддерживать все базы данных, вы должны сериализовать массив в String

class Documents < ActiveRecord::Base
 serialize :share
end

class AddShareToDocuments < ActiveRecord::Migration
 def change
   add_column :documents, :share, :string, :default => []
 end 
end

В случае типа Postgresql и массива я обнаружил https://coderwall.com/p/sud9ja

Ответ 3

Массивы обычно не являются типом, который должен храниться в базе данных. Как указывает michelemina, вы можете сериализовать их в строку и хранить их, если тип данных в массиве прост (строки, int и т.д.). Для вашего случая с электронными письмами вы можете это сделать.

Если, с другой стороны, вы хотите, чтобы найти все объекты пользователя, с которыми был предоставлен документ, есть лучшие способы сделать это. Вам понадобится "таблица соединения". В вашем случае объект join-table можно назвать Share и иметь следующие атрибуты:

class Share
  belongs_to :user
  belongs_to :document
end

Затем, в вашем классе Document,

has_many :shares
has_many :users, :through => :shares

Что касается генерации миграции, это может быть взломанным, но вы можете создать новую миграцию, которая изменит тип на "string" (Edit: correct code):

class AddShareToDocuments < ActiveRecord::Migration
  def up
    change_column :documents, :share, :string
  end
  def down
    change_column :documents, :share, :array, :default => []
  end
end