Add Id column in a migration - ruby-on-rails

I have a Rails app, where one of the models does not have the id column. Doing some research I found the migration that created it:
create_table(:the_model, :id => false) do |t|
# columns
end
Now, on a new migration, I want to add the id column in a Rails standard way (not using database specific sql). How can I do that?
I already tried this without success:
change_table(:the_model, :id => true) do |t|
end

You can either manually add the id column:
add_column :table_name, :id, :primary_key
or clear (or backup) your data, rollback to this migration, get rid of the option :id => false, and re-migrate.

You don't need to mention :integer
rails g migration add_id_to_model id:primary_key worked for me.

You already got your answer, but here is a one liner that does all in this case
rails generate migration AddIdToModel id:integer
Look at the syntax of migration file name AddColumnNameToTableName followed the column description.
It will generate something like below
class AddIdToModel < ActiveRecord::Migration
def change
add_column :models, :id, :integer
end
end
Now you can change this line if you feel for anything else. and just run rake db:migrate.

Related

Rails Migration Add_Index issue

I'm trying to add indexing to my users table for the email column. Typing rails g migration add_index_to_users_email generates the migration but the function is empty. The snake casing should be correct, so I'm at a loss as to why the migration is being created but the change function inside is empty.
I've also tried AddIndexToUsersName and the same issue arises.
Any direction on what the issue could be would be greatly appreciated. Only thing I can think of is that I'm using Postgres and not MySQL or SQLite, but that wouldn't matter would it?
As far as I know, migration generators only support addition and removal of columns, with a specified modifier. For example, if you wished to add a new string column phone to the users table, you could use the command
rails generate migration AddPhoneToUsers phone:string
Check the Rails Guides for column modifiers. You can try
rails generate migration AddIndexToUsers email:index
to add an index to the existing column. However, I am not sure if generators support column modification. You can write the migration yourself, assuming the email column already exists on the users table:
class AddIndexToUsers < ActiveRecord::Migration
def change
add_index :users, :email
end
end
Have a look at:
http://guides.rubyonrails.org/active_record_migrations.html
The correct command is
rails g migration AddIndexToUsers email:string:index
This will generate:
class AddIndexToUsers < ActiveRecord::Migration
def change
add_column :users, :email, :string
add_index :users, :email
end
end
Edit the migration file and delete the add_column line, then run the migration.

Add primary key to schema_migrations table

I would like to run the following migration to my Rails(4.x) app but would like to get some feedback from the Rails community first.
class AddUniqueIndexToSchemaMigrations < ActiveRecord::Migration
def change
add_column :schema_migrations, :id, :primary_key
add_index :schema_migrations, ["version"], :name => "unique_versions", :unique => true
end
end
The database in use is MySQL (5.x). Adding this index allows me execute SQL such as:
INSERT INTO schema_migrations
(version)
VALUES ( '2014xxxxxx' )
ON DUPLICATE KEY
UPDATE foo=bar; // or some other bit of cleverness
Is there any reason why this is going off the rails? I don't want to create a situation where I'm fighting against Rails internals.
Thanks in advance!

Missing table column, defined in migrate

I tried to create a new Link table and specified the necessary columns under migration.
under db/migrate
class CreateLinks < ActiveRecord::Migration
def change
create_table :links do |t|
t.integer :user_id
t.string :url
t.timestamps
end
end
end
class AddTitleToLink < ActiveRecord::Migration
def change
# add_column :links, :user_id, :integer
add_column :links, :title, :string
end
end
When I ran rails console, Link returned
Link(id: integer, created_at: datetime, updated_at: datetime, title: string)
It seems like user_id (the foreign key) and url are missing. Title, which was added later, is in the table.
Did I do anything wrong?
Did you perhaps run the CreateLinks migration before editing it to add the two fields? If so, you can change that file all day long and rake db:migrate will never re-run it. That would explain there being an empty table links, and the field you then added to it in the next migration.
You can step the database back by running rake db:rollback. Try doing that twice, then migrate again.
Can't see any reason for this not to work. Is it possible that you first ran:
rails g model Link
(which generated a migration AND RAN it)
and then you manually added the :url and :user_id?
Try running twice:
rake db:rollback
Then run again
rake db:migrate
which will catch up your manual modifications

ruby on rails add a column after a specific column name

I tried to add a column to a table after a specific column in the table.
Here is what I did:
rails generate migration add_reaction_id_to_patient_allergies reaction_id: integer :after => 'patient_id'
Here is what my migration file looks like:
class AddReactionIdToPatientAllergies < ActiveRecord::Migration
def change
add_column :patient_allergies, :reaction_id, :string
add_column :patient_allergies, :integer, :string
add_column :patient_allergies, :, :after
add_column :patient_allergies, :=, :string
end
end
I dont think the command went well. I see an '=' in the above file. I do not think it should be there. Can someone tell me if I missed anything?
If so , how do I undo the above?
I doubt it allowed you to actually rake db:migrate this migration, so you shouldn't have to roll back. Just remove the bottom three add_columns and replace the top one with
add_column :patient_allergies, :reaction_id, :integer, after: :patient_id
and it should be fine to migrate. For future reference, here's what that command you entered should look like:
rails generate migration add_reaction_id_to_patient_allergies reaction_id:integer
The space before integer made the generator think it was a new column. Sadly you can't use Ruby syntax (a => b) on the command line either.

RAILS: DB MIGRATION: resetting id column to auto_increment

When I created the table users, the resulting table had a column called id, defined as an integer.
I tried to modify it to bigint, unsigned as follows:
change_column :users, :id, :integer, :limit => 8, :unsigned => true
Which did change it to bigint, but it was no longer an auto-increment column (though it was still identified as the primary index, and it was not set to unsigned (even though rails told me that the migration executed fine)
I then tried doing:
change_column :users, :id, :integer, :limit => 8, :unsigned => true, :null => false, :auto_increment => true
Rails said that the migration executed fine, but nothing changed.
I could try something like:
change_column :users, :id, :primary_index
but that would put me right where I started
I could also try an "execute" statement with MySQL code, but I want to keep the migration file "clean". Has anyone run into this issue?
As an aside, I was also trying to set the default to NULL on another column, researched it here (and Google), with no success.
EDIT:
It seems as if there is no way to edit the column "id" after it is created as part of table creation through a generic migration. The only way to do this is through an "execute" statement with MySQL syntax.
Try creating and running this migration:
class ChangeColumnUserIdToAutoIncrement < ActiveRecord::Migration
def self.up
execute "ALTER TABLE users modify COLUMN id int(8) AUTO_INCREMENT"
end
def self.down
execute "ALTER TABLE users modify COLUMN id int(8)"
end
end
Rails is taking care for you the ID field of all the tables you're creating and it's hidden from your migrations and even from the schema.rb file.
So I would advice you to take a step back and think: Why would you want to mess with it? Are you sure that's really needed?
EDIT: This answer seems to be exactly what you're looking for.
Regarding "setting default to NULL", again, why would you do that? All the columns are defaulting to NULL anyway. However, if that's not the case you could do that in a migration:
change_table :users do |t|
t.string :description, :default => nil
end
Hope that answers your question.

Resources