add_column для ссылок (Rails)

У меня есть следующая миграция Rails, которая отлично работает (удалены ненужные части):

create_table :comments do |t|
  t.text :body
  t.references :post
end

Теперь я хотел бы добавить столбец author в свою таблицу comments (которая является идентификатором пользователя пользователя), но я понятия не имею, как это сделать (у меня возникает соблазн просто написать специфичный для MySql синтаксис с использованием execute) .

Я просматривал add_column здесь, в котором не упоминается references. На самом деле я нашел TableDefinition#references, но понятия не имею как использовать его с оператором add_column.

Это возможно? Кроме того, правда ли, что для MySql функция «ссылки» фактически не устанавливает отношения между таблицами?


person Dan Rosenstark    schedule 29.01.2009    source источник


Ответы (6)


Хотя уже слишком поздно извлекать из этого какие-либо очки, я решил опубликовать лучший способ для потомков :)

используйте change_table вместо create_table для добавления столбцов в уже существующую таблицу со всеми достоинствами TableDefinition:

self.up do
  change_table :comments do |t|
    t.references :author
  end
end

Это может показаться тривиальным, но другие драгоценные камни, такие как Devise, интенсивно используют свои собственные определения пользовательских таблиц, и таким образом вы все еще можете их использовать.

person Jaime Bellmyer    schedule 15.10.2010
comment
Итак, я добавляю поле автора в таблицу комментариев и использую ссылки. Это имеет значение для MySql? Мне все еще нужно изменить модель? - person Dan Rosenstark; 16.10.2010
comment
Да, вам все равно нужно будет добавить has_many :comments в ваш author.rb, и created_to :author в ваш comment.rb. Код миграции только создает поля в базе данных, которые бесполезны до тех пор, пока вы не вызовете правильные методы ActiveRecord, которые я здесь перечислил. - person Jaime Bellmyer; 16.10.2010
comment
Это все еще лучший способ в rails3? Кроме того, это действительно должно быть помечено как ответ... - person docwhat; 18.10.2010
comment
Да, это лучший способ. На самом деле, я только что использовал его в приложении для рельсов 3 на этих выходных (во время Rails Rumble). И я опоздал почти на 2 года, чтобы отметить правильный ответ - это старый вопрос! - person Jaime Bellmyer; 19.10.2010
comment
@Jaime Bellmyer, если вы используете @yar в своем комментарии и говорите, почему этот ответ превосходит лучший ответ, я отмечу его. - person Dan Rosenstark; 19.10.2010
comment
@yar - это лучший ответ, потому что пользователь спрашивал, как получить определения таблиц, такие как t.references, чего нельзя сделать с помощью add_column. Драгоценный камень Devise реализует свои собственные определения пользовательских таблиц, поэтому вам не нужно заполнять свои миграции десятками трудно запоминающихся имен полей. Будем надеяться, что эта практика станет более популярной с драгоценными камнями и плагинами в рельсах. - person Jaime Bellmyer; 20.10.2010
comment
@ Хайме Беллмайер, хорошо, +1 и лучший ответ, и я тоже кое-чему научился. Я думаю, мне тоже придется проверить драгоценный камень Devise. Спасибо! - person Dan Rosenstark; 20.10.2010
comment
@Jamie Bellmyer Как лучше всего выполнить обратную миграцию? Мне нравится, чтобы мои миграции были чистыми в обоих направлениях. - person Jackson Miller; 07.02.2011
comment
@Jackson Miller, нет t.unreference для отмены добавления ссылки, но вы можете использовать длинный путь с t.remove : author_id в приведенном выше примере. Если вы использовали t.references :author, :polymorphic =› true, вам также потребуется t.remove author_type при миграции вниз. - person Jaime Bellmyer; 16.03.2011
comment
К сожалению, этому ответу 4-5 лет. Несмотря на то, что это может работать, это уже неприемлемый метод для Rails 4+. Пожалуйста, ознакомьтесь с СУХИМ однострочным предложением Раджива Каннава Шармы и Джоша Крозье. - person Eric Wanchic; 28.01.2015

Наконец получил это

add_column :locations, :state_id , :integer, :references => "states"
person Swapnil Chincholkar    schedule 21.04.2011
comment
Чикоклкар, это здорово. Если бы вы могли удалить свой другой ответ, а также если бы вы могли дать ссылку на документы Rails, это было бы здорово. Спасибо! - person Dan Rosenstark; 22.04.2011
comment
Это действительно делает что-то особенное? Я не могу найти никакой документации, в которой говорится, что add_column действительно что-то делает с символом :references в опциях. - person Ibrahim; 26.04.2013
comment
Вероятно, это был правильный ответ в 2012 году, но с Rails 4 это ответ @rajeev-kannav-sharma. - person zmilojko; 13.10.2014

Сначала выполните:

script/generate migration AddAuthorIdToComments

Откройте сгенерированный файл и добавьте эту строку:

add_column :comments, :author_id, :integer

Затем в ваших файлах модели:

class User < ActiveRecord::Base
  has_many :comments, :foreign_key => "author_id"
end

class Comment
  belongs_to :author, :class_name => User
end
person Milan Novota    schedule 29.01.2009
comment
очень приятно, спасибо за это. Конечно, добавление столбца в виде целого числа - это не то, на что я надеялся, но поскольку исходная миграция все равно делает это ... СПАСИБО за описание того, как настроить отношения в классах модели. - person Dan Rosenstark; 30.01.2009
comment
Простая истина в том, что вы просто не можете использовать ссылки в этом сценарии, потому что они доступны только для определений таблиц. И да, как говорит Крейг, миграции не заботятся об установке внешних ключей в базе данных. - person Milan Novota; 30.01.2009
comment
Хорошо, я понял: определения таблиц: на уровне столбца это недоступно (только на уровне таблицы). Вопрос: если столбец в User называется id, то работает, да? author_id — это имя нового столбца ТОЛЬКО в комментариях, верно? - person Dan Rosenstark; 30.01.2009
comment
Да, связь между этими двумя определяется на уровне модели (см. Foreign_key, class_name). - person Milan Novota; 30.01.2009
comment
Что делает class_name => User? - person AnApprentice; 14.09.2010
comment
Только для протокола. Имя класса должно каждый раз в . Таким образом, правильный синтаксис: принадлежит_кому :автор, :класс_имя => Пользователь, а не принадлежит_кому :автор, :класс_имя => Пользователь - person ThreeFingerMark; 21.01.2011

Прошло некоторое время с тех пор, как я смотрел на это, но в последний раз я проверял, что миграции не поддерживают создание внешних ключей. Однако, к счастью, для есть подключаемый модуль. Я использовал это, и это работает хорошо.

person Craig Stuntz    schedule 29.01.2009

Вы можете добавить столбец add_column(:table, :column_name, :type, :options) в новую миграцию.

person Community    schedule 29.01.2009
comment
Спасибо, Майк. Какими будут :type и :options? - person Dan Rosenstark; 30.01.2009

person    schedule
comment
Это хороший ответ, по крайней мере, для Rails 4. Здесь справочник по API - person fguillen; 08.09.2014
comment
Согласованный. Теперь это должен быть «новый» правильный ответ для Rails 4+. - person Eric Wanchic; 28.01.2015
comment
Вы также можете пройти add_reference :table_name, :reference, polymorphic: true, index: true - person Scudelletti; 05.05.2015