user1781626
user1781626

Reputation:

Destroying a Model in Rails

I want to destroy the following model:

class Job < ActiveRecord::Base
  has_many :items
  validates :name, presence: true, uniqueness: true
end

This is the Item Model

class Item < ActiveRecord::Base
  belongs_to :department
  belongs_to :job
  belongs_to :category
  validates :name, presence: true, uniqueness: true
end

I know I'm going to use rails d model Job

but how to delete the column job_id in the Item Model? is it db:rollback? and how to make sure everything is clean? What else should I do?

Upvotes: 0

Views: 975

Answers (4)

TwiceB
TwiceB

Reputation: 959

You can generate a migration which will remove the indexed job_id. No manual migration file modifications needed. Simply:

rails g migration RemoveJobRefFromItems job:references

Upvotes: 0

makewavesnotwar
makewavesnotwar

Reputation: 1015

Assuming you also put an index on your job_id column, you're going to want to remove that before you remove the column. Also if you're running rails 3.1+ you can skip the up/down methods and just use a change method on something simple like this, otherwise I would completely agree with zeantsoi. For your migration:

def change
  remove_index :items, :job_id
  remove_column :items, :job_id
end

Also, if your column doesn't have an index: index your foreign keys.

Upvotes: 0

IAmNaN
IAmNaN

Reputation: 10582

If it's just you and you can live without the data in the Item table, then:

  • run rake db:rollback twice to delete both the Job and Item table
  • run rails d model Job to delete the Job model and migrations
  • edit the Item migration file to manually remove the belongs_to :job line
  • and finally rake db:migrate to get things back to normal

When working with a group, you don't know if they have already ran migrations that added job_id, so this is safer:

  • run rails g migration remove_job_id_from_items job_id:integer to create a migration that removes job_id from the Item table
  • run rails g migration drop_items_table to drop the table and edit this migration to add drop_table :job to the change block (see note below)
  • run rake db:migrate to bring those two migrations you just created forward.
  • and finally run rails d model Job --skip-migration to destroy the model but leave the original migration

When you do it this way, both migrations stay in your project forever, but cancel each other out. In git, we try to only move forward.

(note: this may create an "irreversible migration" and there may be a better way to do this step.)

Upvotes: 0

zeantsoi
zeantsoi

Reputation: 26203

We can't tell from the information provided whether you can simply run a down migration to removed the job_id column, since it might be destructive to other columns. However, you can create a new migration that explicitly deletes the job_id column:

# from command line
rails g migration RemoveJobIdFromItems

Specify the column to remove in your table:

def up
  remove_column :items, :job_id
end

In case you want to re-add the migration, create a down migrations that rolls back the removal:

def down
  add_column :items, :job_id, :integer
end

Then run rake db:migrate from command line. The column will be removed from the items table.

Finally, you'll want to ensure that you've removed the association from your model:

# app/models/item.rb
class Item < ActiveRecord::Base
  belongs_to :department
  belongs_to :category
  validates :name, presence: true, uniqueness: true
end

Upvotes: 2

Related Questions