I have one table called profiles with some columns.
Now I wish to add a few columns to this table using the change-method in rails 3.1. I created a migration with the following code:
def change
change_table :profiles do |t|
t.string :photo
t.string :name
t.references :user
end
end
The migration works perfectly, but when I want to rollback I get
SQLite3::SQLException: duplicate column name: photo: ALTER TABLE "profiles" ADD "photo" varchar(255)
Any ideas why?
The auto-generated migrations for adding columns in Rails 3.1 is in the format:
class AddColumnToTable < ActiveRecord::Migration
def change
add_column :table, :column, :type
end
end
Perhaps try that syntax?
It looks like you need to tell the migration how to revert itself:
def change
change_table :profiles do |t|
t.string :photo
t.string :name
t.references :user
end
reversible do |dir|
dir.down do
remove_column :profiles, :photo
remove_column :profiles, :name
remove_column :profiles, :user_id
end
end
end
See http://guides.rubyonrails.org/migrations.html#using-reversible for more information.
Alternatively you could try using the old up and down methods which are still available like so:
def up
change_table :profiles do |t|
t.string :photo
t.string :name
t.references :user
end
end
def down
remove_column :profiles, :photo
remove_column :profiles, :name
remove_column :profiles, :user_id
end
More on up/down here: http://guides.rubyonrails.org/migrations.html#using-the-up-down-methods
Related
I wanna rename the column id, how do I do?
I want to set number to primary key and auto increment, and id to just string of user id.
How do I do?
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :user
t.timestamps
end
rename_column :users, :id, :number
end
end
I did like above, but it didn't work.
Even if I wouldn't recommend it, here is how I guess you can do it:
in your migration:
def up
create_table :users, id: false do |t|
t.string :user
t.integer :number, null: false, index: true, unique: true
t.timestamps
end
execute %Q{ ALTER TABLE "users" ADD PRIMARY KEY ("number"); }
end
def down
drop_table :users
end
in your model:
self.primay_key = 'number'
Since I am new to Rails, I am following this 'getting started' guide on rails website.
On section 6.1 Generating a Model, I should run rails generate model Comment commenter:string body:text post:references to get a comment model.
Supposedly, this is what should be included in the migration file:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post
t.timestamps
end
add_index :comments, :post_id
end
end
But in my migration file, I have everything but this line add_index :comments, :post_id.
Instead, I have index:true following the t.references :post
I can't seem to find an explanation to this, can anyone explain to me what is going on here? Because later on I need to use :post_id, but in my version of migration, it is not clearly declared. I am very confused.
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post
t.timestamps
end
add_index :comments, :post_id
end
end
and
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post, index: true
t.timestamps
end
end
end
will do same things, both of them will add index to post_id column
also you can later add index to any column any column that you want to add to your model like
$ rails generate migration AddPartNumberToProducts part_number:string:index
that will produce this code:
class AddPartNumberToProducts < ActiveRecord::Migration
def change
add_column :products, :part_number, :string
add_index :products, :part_number
end
end
in above code if you want to create index for post_id then write it as t.integer :post_id
else you can try this add_index :comments, :post
So I am trying to create three models, Project, Entry and User. A Project has many Entries, and a a User has many Entries. I scaffolded the above three models with the following commands:
rails g scaffold Project title:string
rails g scaffold Entry project:project_id entry_for:user_id created_by:userid \
date:string start_time:string end_time:string total:string type_of_work:string \
on_off_site:string phase:string description:text
rails g scaffold User name:string
I realize that I probably totally goofed up the part where I manually put in the foreign keys for the other tables in the Entry model. I don't know how much has_many belongs_to automates the relationship between different models in terms of keys so I tried to add the foreign key fields manually. Is this wrong?
When I try to run db:migrate I get the following error:
undefined method `user_id' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0x007fc1bdf37970>
Here are my migrations, as I tried to remove all of the foreign key fields but got the above error.
class CreateProjects < ActiveRecord::Migration
def change
create_table :projects do |t|
t.string :name
t.timestamps
end
end
end
class CreateEntries < ActiveRecord::Migration
def change
create_table :entries do |t|
t.string :project
t.string :project_id
t.user_id :entry_for
t.user_id :created_by
t.string :date
t.string :start_time
t.string :end_time
t.string :total
t.string :type_of_work
t.string :on_off_site
t.string :phase
t.text :description
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
class RemoveColumns < ActiveRecord::Migration
def self.up
remove_column :entries, :created_by
remove_column :entries, :entry_for
remove_column :entries, :project_id
end
def self.down
add_column :entries, :created_by, :user_id
add_column :entries, :entry_for , :user_id
add_column :entries, :project_id, :string
end
end
Thank you for your help!
In your migrations, instead of t.user_id you can try t.integer or t.index. That should at least get your migrations running.
I am going to use t.references entry_for and then write belongs_to :entry_for, class_name: "User" in the Entry model as a means of writing my own foreign key name. For the project column in entries I realized I can similarly write t.references project.
I want to add to my model Treatment an column, so that it belongs_to a category:
class CreateTreatments < ActiveRecord::Migration
def change
create_table :treatments do |t|
t.string :typ
t.string :content
t.date :day
t.references :patient
t.timestamps
end
add_index :treatments, :patient_id
add_index :treatments, :category_id
end
end
i want to add:
t.references :category
and
add_index :treatments, :category_id
I tried it simply copying it in and running a migration but it didnt`t worked! I know normally i would simply make an
rails g model Treatment category:references
How can i achieve this afterwards?
You should generate another migration:
rails g migration add_category_id_to_treatments category_id:integer
You ought to edit automatically generated migration and add line on the end of change method:
add_index :treatments, :category_id
Then you should run migration.
I'm having this table
class CreateEvents < ActiveRecord::Migration
def self.up
create_table :events do |t|
t.integer :subcategory
t.string :event_name
t.text :description
t.string :location
t.date :date
t.decimal :price
t.timestamps
end
end
def self.down
drop_table :events
end
end
and i want to change the subcategory to subcategory_id. I tries this one but is not working
ruby script/generate migration RenameDatabaseColumn and then i went to the file which is in db\migrate and edited to look like this
class RenameDatabaseColumn < ActiveRecord::Migration
def self.up
rename_column :events, :subgategory, :subgategory_id
end
def self.down
# rename back if you need or do something else or do nothing
end
end
then i run the command rake db:migrate put the column is still subcategory. Can you help me please? I'm using rails 2.0
Thank you
Did you misspell the column name? isn't it :subcategory? You wrote :subgategory.
class RenameDatabaseColumn < ActiveRecord::Migration
def self.up
rename_column :events, :subcategory, :subcategory_id
end
def self.down
# rename back if you need or do something else or do nothing
end
end