max
max

Reputation: 102230

How to write a migration for a rails model that belongs_to itself

model scenario:

A node can belong to a parent node and can have child nodes.

models/node.rb

class Node < ActiveRecord::Base                                                                

  has_many :children, class_name: "Node", foreign_key: "parent_id"                             
  belongs_to :parent, class_name: "Node"                                                       

end           

db/migrations/20131031144907_create_nodes.rb

class CreateNodes < ActiveRecord::Migration
  def change
    create_table :nodes do |t|
      t.timestamps
    end
  end
end   

And then I want to do I migration to add the relations:

class AddNodesToNodes < ActiveRecord::Migration
  def change
    add_column :nodes, :parent_id, :integer
    # how do i add childen?
  end
end

How do i add the has_many relationship in the migratation?

Upvotes: 14

Views: 11648

Answers (4)

go2null
go2null

Reputation: 2308

Per RailsGuides, this is an example of a Self-Join.

# model
class Node < ActiveRecord::Base
  has_many :children, class_name: "Node", foreign_key: "parent_id"
  belongs_to :parent, class_name: "Node"
end

# migration
class CreateNodes < ActiveRecord::Migration
  def change
    create_table :nodes do |t|
      t.references :parent, index: true
      t.timestamps null: false
    end
  end
end

Upvotes: 13

Michael Durrant
Michael Durrant

Reputation: 96544

You've already written the migration with your AddNodeToNodes and the parent ID.

That defines it at the database level.

At the 'rails' level (ActiveRecord) you define the has_many in the model definition, i.e the Node.rb file that define the Node class.
There is no 'migration' to add has_many. Migrations are used for database fields (and indexes, etc.) such a as parent_id but not for rails style relationship definitions such as has_many.

Upvotes: 1

JeskTop
JeskTop

Reputation: 481

You've done everything you needed to do.You can find the more informations in this page: enter image description here

Source: http://guides.rubyonrails.org/association_basics.html

node.parent will find the parent_id is the node id and return the parent.

node.children will find the parent_id is the node id and return the children.

And when you add relations, you can do like this in Rails 4:

## rails g migration AddNodesToNodes parent:belongs_to

class AddNodesToNodes < ActiveRecord::Migration
  def change
    add_reference :nodes, :parent, index: true
  end
end

Upvotes: 13

Peter Goldstein
Peter Goldstein

Reputation: 4545

There's no need for anything additional in the migration. The parent_id is used to define the relationship in both directions. Specifically:

  1. parent - The Node with the id corresponding to the value of the parent_id attribute for the current Node.

  2. children - All Nodes with a parent_id value corresponding to the value of the id attribute for the current Node.

Upvotes: 1

Related Questions