可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have created a User
model and later a Task
model. I have not mentioned any relation between them while creating.
I understand that User
has_many
Tasks
and a Task
belongs_to
User
. I need to establish this relation between them through migration.
My question is, what would be the migration generation command for establishing that relation?
Any help would be highly appreciated.
回答1:
You could call:
rails g model task user:references
which will generates an user_id
column in the tasks
table and will modify the task.rb
model to add a belongs_to :user
relatonship. Please note, you must to put manually the has_many :tasks
or has_one :task
relationship to the user.rb
model.
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 :user
relationship in the task.rb
model won't be created automatically, so you must create it for your own.
回答2:
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
)
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_to
is just an alias of :references
, so either will do the same thing.
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.
回答3:
How it should be done when creating the migration in the first place:
rails g scaffold child parent:references
What to do if you've forgotten the parent:references
bit:
If you don't really have a lot defined in the model/db about the child. Your best bet might just be to run rails destroy scaffold child
, and then run
rails g scaffold child parent:references
over it. Be sure to add the line drop_table :children if table_exists? :children
before 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 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 for some more detail.
Also don't forget to make sure that the parent model has_[one | many] :children
, and that the child model belongs_to :parent
.
How not to do it:
You may be tempted just to go in and add the parent_id manually, and you certainly could, this not the best solution as it is not the conventional way to go about adding foreign keys, and doesn't lend itself very well to maintainability or readability. Convention over configuration!
The Ruby on Rails guide to association also has more helpful information on the subject.
回答4:
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
Take a look at this guide
回答5:
The migration will add the user's id to the task table so they know about each other
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
回答6:
The Relationship in Rails is taken care by model not by 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_id
field is present in the migration for creating the "tasks" table.