Ruby-on-rails 活动记录迁移 rails 4 中的 has_many、belongs_to 关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17894688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
has_many, belongs_to relation in active record migration rails 4
提问by Hasan Iqbal
I have a Usermodel and a Taskmodel. I have not mentioned any relation between them while creating them.
我有一个User模型和一个Task模型。我在创建它们时没有提到它们之间的任何关系。
I need to establish that Userhas_manyTasksand a Taskbelongs_toUserthrough a migration
我需要建立Userhas_manyTasks和Taskbelongs_toUser通过迁移
What would be the migration generation command for establishing that relationship?
建立这种关系的迁移生成命令是什么?
回答by Alter Lagos
You could call:
你可以打电话:
rails g model task user:references
which will generates an user_idcolumn in the taskstable and will modify the task.rbmodel to add a belongs_to :userrelatonship. Please note, you must to put manually the has_many :tasksor has_one :taskrelationship to the user.rbmodel.
这将user_id在tasks表中生成一列,并将修改task.rb模型以添加关系belongs_to :user。请注意,您必须手动放置与模型的has_many :tasks或 has_one :task关系user.rb。
If you already have the model generated, you could create a migration with the following:
如果您已经生成了模型,则可以使用以下内容创建迁移:
rails g migration AddUserToTask user:belongs_to
which will generate:
这将产生:
class AddUserToTask < ActiveRecord::Migration
def change
add_reference :tasks, :user, index: true
end
end
the only difference with this approach is, the belongs_to :userrelationship in the task.rbmodel won't be created automatically, so you must create it for your own.
这种方法的唯一区别是,模型中的belongs_to :user关系task.rb不会自动创建,因此您必须为自己创建它。
回答by chad_
To answer the question, "What would be the migration generation command for establishing that relation?"( Meaning, how do you add a migration for existing models with a relationship like User has_many Tasks& Task belongs_to User)
要回答这个问题,“建立该关系的迁移生成命令是什么?”(意思是,您如何为具有User has_many Tasks& 等关系的现有模型添加迁移Task belongs_to User)
The the easiest way for me to remember is like this:
我最容易记住的方法是这样的:
>rails g migration AddUserToTask user:belongs_to
or
或者
>rails g migration AddUserToTask user:references
:belongs_tois just an alias of :references, so either will do the same thing.
:belongs_to只是 的别名:references,所以两者都会做同样的事情。
Doing it this way, the command will infer the name of the table from the migration name, set up a change method that will add the column for relationship, and configure it to be indexed:
这样做,该命令将从迁移名称推断表的名称,设置一个更改方法来添加关系列,并将其配置为索引:
class AddUserToTask < ActiveRecord::Migration
def change
add_reference :tasks, :user, index: true
end
end
After generating that you:
生成后,您:
>rake db:migrate
Finally, you still have to add the usual relations to your models, as is stated in the other answers, but I think this is the right answer to your question.
最后,您仍然需要为模型添加通常的关系,如其他答案中所述,但我认为这是您问题的正确答案。
回答by 0112
This is how the migration should be created normally:
这是通常应该如何创建迁移:
rails g scaffold child parent:references
rails g scaffold child parent:references
I forgot to add parent:referenceswhen I created the table, what should I do?
parent:references建表的时候忘记加了,怎么办?
Option 1: Destroy the table and start over
选项 1:销毁桌子并重新开始
If you don't have a lot defined in the model/db about the child table. Your best bet might just be to run rails destroy scaffold child, and then run
rails g scaffold child parent:referencesover it. Be sure to add the line drop_table :children if table_exists? :childrenbefore create table in the file that creates the new table. (That way if anyone pulls your code they can just run the migrations and be done.) However, it seems more probable that you will have data you don't want to lose in the child model already.
In that case:
如果您没有在模型/数据库中定义很多关于子表的内容。您最好的选择可能只是运行rails destroy scaffold child,然后
rails g scaffold child parent:references碾过它。确保drop_table :children if table_exists? :children在创建新表的文件中在 create table 之前添加行。(这样,如果有人提取您的代码,他们就可以运行迁移并完成。)但是,您似乎更有可能拥有不想在子模型中丢失的数据。在这种情况下:
Option 2: Write a migration to add the references
选项 2:编写迁移以添加引用
rails g migration add_parent_refs_to_child
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
See add_reference
Additionally, don't forget to make sure the parent model has_[one | many] :children, and that the child model belongs_to :parent.
此外,不要忘记确保父模型has_[one | many] :children和子模型belongs_to :parent。
How not to do it:
如何不这样做:
You may be tempted to add the parent_idmanually. Don't. Conventionally this sort of operation is handled through a migration, or within the initial table creation. Manual addition will detract from the maintainability of the project.
您可能想parent_id手动添加。别。通常,此类操作是通过迁移或在初始表创建中处理的。手动添加会降低项目的可维护性。
The Ruby on Rails guide to associationhas more information on the subject.
在Ruby on Rails的指导协会对主题的更多信息。
回答by Althaf Hameez
There is no special migration command that would be used.
没有可以使用的特殊迁移命令。
In your User model you will put
在您的用户模型中,您将放置
class User < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :user
end
In the corresponding migration file for the tasks you have the following field added user_id
在任务的相应迁移文件中,您添加了以下字段 user_id
Take a look at this guide
看看这个指南
回答by Amitkumar Jha
The Relationship in Rails is taken care by model not by Rails.
Rails 中的关系由模型处理,而不是由 Rails 处理。
So you just need to define this relationship in your model:
所以你只需要在你的模型中定义这个关系:
class User < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :user
end
And just make sure that a user_idfield is present in the migration for creating the "tasks" table.
只需确保user_id迁移中存在用于创建“任务”表的字段。
回答by Connor Leech
The migration will add the user's id to the task table so they know about each other
迁移会将用户的 id 添加到任务表中,以便他们相互了解
rails g migration AddUserIdToTask user_id:integer
then
然后
rake db:migrate
And after update your controllers and views so that tasks can't be created on their own but must correspond to a user
并且在更新您的控制器和视图之后,任务不能自己创建,但必须对应于用户

