Отношение has_many,members_to в рельсах миграции активных записей 4

У меня есть модель User и модель Task. Я не упомянул о какой-либо связи между ними при их создании.

Мне нужно установить, что User has_many Tasks и Task belongs_to User через миграцию

Какой будет команда генерации миграции для установления этой связи?


person QuestionEverything    schedule 27.07.2013    source источник
comment
Я надеюсь, что эта ссылка поможет вам решить stackoverflow.com/questions/11354724/   -  person Ghayathri    schedule 27.07.2013
comment
Не могли бы вы отметить ответ @Alter_Lagos как правильный, чтобы помочь другим?   -  person s89_    schedule 28.03.2019


Ответы (6)


Вы можете позвонить:

rails g model task user:references

который создаст столбец user_id в таблице tasks и изменит модель task.rb, чтобы добавить отношение belongs_to :user. Обратите внимание, что вы должны вручную установить отношение has_many :tasks или has_one :task к модели user.rb.

Если у вас уже есть сгенерированная модель, вы можете создать миграцию со следующим:

rails g migration AddUserToTask user:belongs_to

который будет генерировать:

class AddUserToTask < ActiveRecord::Migration
  def change
    add_reference :tasks, :user, index: true
  end
end

единственная разница в этом подходе заключается в том, что отношение belongs_to :user в модели task.rb не будет создано автоматически, поэтому вы должны создать его самостоятельно.

person Alter Lagos    schedule 29.07.2013
comment
Я думаю, было бы неплохо отметить, что :belongs_to является псевдонимом :references. Хороший ответ, хотя. :) - person chad_; 21.05.2015

Чтобы ответить на вопрос: «Какой будет команда генерации миграции для установления этого отношения?» (имеется в виду, как добавить миграцию для существующих моделей с такими отношениями, как User has_many Tasks и Task belongs_to User)

Мне проще всего запомнить так:

>rails g migration AddUserToTask user:belongs_to

or

>rails g migration AddUserToTask user:references

:belongs_to — это просто псевдоним :references, поэтому любой из них будет делать то же самое.

Сделав это таким образом, команда выведет имя таблицы из имени миграции, настроит метод изменения, который добавит столбец для связи, и настроит его для индексации:

class AddUserToTask < ActiveRecord::Migration
  def change
    add_reference :tasks, :user, index: true
  end
end

После создания этого вы:

>rake db:migrate

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

person chad_    schedule 22.09.2014

Вот как обычно должна создаваться миграция:

rails g scaffold child parent:references


Я забыл добавить parent:references при создании таблицы, что мне делать?

Вариант 1. Уничтожить таблицу и начать заново

Если у вас мало что определено в модели / БД о дочерней таблице. Лучше всего просто запустить rails destroy scaffold child, а затем запустить rails g scaffold child parent:references поверх него. Обязательно добавьте строку drop_table :children if table_exists? :children перед созданием таблицы в файле, который создает новую таблицу. (Таким образом, если кто-то возьмет ваш код, он сможет просто запустить миграцию и сделать это.) Однако кажется более вероятным, что у вас уже будут данные, которые вы не хотите потерять в дочерней модели. В этом случае:

Вариант 2. Напишите миграцию для добавления ссылок

rails g migration add_parent_refs_to_child

## XXXXXXXXXXXXXX_add_parent_refs_to_child.rb
class AddParentRefsToChild < ActiveRecord::Migration
  def change
    add_reference :child, :parent, index: true
  end
end

См. add_reference.

Кроме того, не забудьте убедиться, что родительская модель has_[one | many] :children и дочерняя модель belongs_to :parent.


Как этого не делать:

У вас может возникнуть соблазн добавить parent_id вручную. Не надо. Обычно операции такого рода выполняются посредством миграции или при первоначальном создании таблицы. Ручное добавление ухудшит ремонтопригодность проекта.

Руководство по ассоциации Ruby on Rails содержит дополнительную информацию по этому вопросу.

person 0112    schedule 01.10.2014

Нет специальной команды миграции, которую можно было бы использовать.

В вашей модели пользователя вы поместите

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

В соответствующем файле миграции для задач у вас добавлено следующее поле user_id

Ознакомьтесь с этим руководством.

person Althaf Hameez    schedule 27.07.2013
comment
Это хорошо, однако, если пользователи таблицы не включают t.references :user в задачу создания таблицы, то этот ^ не будет иметь никакого эффекта. - person 0112; 01.10.2014

Миграция добавит идентификатор пользователя в таблицу задач, чтобы они знали друг о друге.

rails g migration AddUserIdToTask user_id:integer

тогда

rake db:migrate

И после обновите свои контроллеры и представления, чтобы задачи не могли создаваться сами по себе, а должны соответствовать пользователю

person Connor Leech    schedule 18.11.2013
comment
Это немного хак, вместо этого вы должны убедиться, что при определении таблицы вы говорите t.references :user. Или, если таблица уже была создана без него, напишите миграцию, которая сделает это за вас. - person 0112; 01.10.2014

Отношения в Rails регулируются моделью, а не Rails.

Итак, вам просто нужно определить это отношение в вашей модели:

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

И просто убедитесь, что в миграции присутствует поле user_id для создания таблицы «задачи».

person Amitkumar Jha    schedule 27.07.2013
comment
да jha .. я мог бы добавить это, просто хотел узнать команду миграции в терминале. - person QuestionEverything; 27.07.2013
comment
в этом случае просто запустите rails, создайте миграцию add_user_id_to_task. он сгенерирует файл миграции от вас, и здесь вы можете добавлять и удалять столбцы - person Amitkumar Jha; 27.07.2013