Hi I created a table for a wiki application that I was doing. It was pretty simple in the beginning I had a Questions table and an Answers table. I now want to add users to it. So for that I created a users table and the whole signup thing is ready. The wiki part is working and the users part is working but I am having trouble to merge them together.
I first created a Questions as a scaffold as follows:
rails g scaffold Question title:string body:string
Then Answers as follows:
rails g scaffold Answer question_id:integer content:string
I then tried to add the users_id column after creating the Users table:
rails generate migration add_users_id_to_questions user_id:integer
I then tried to index the user_id column by adding the following line in the migration file:
class AddUserIdToQuestions < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
end
add_index :questions, :user_id
end
I do rake:db migrate but it doesnt show the change after I run migration. Is there any other way I can index user_id other than by adding a column to the migration file. I even ran rake db:rollback so the addition of user_id column is gone but when I make the change and run rake db:migrate it gives me an error user_id doesnt exist. It would be greatly appreciated if you could help me how to create the index. I running Rails 3, SQLite as my DB.
Thank you.
Rollback and then re-run the migration with add_index inside the change block.
class AddUserIdToQuestions < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
add_index :questions, :user_id
end
end
Related
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.
As the title suggests, I accidentally add some random attachment columns to my model. Say I did rails generate paperclip portfolio href
How do I remove those columns created? rails destroy paperclip portfolio href doesnt seem to work!
For recent version rails 4++ Just create a migration Example:
rails g migration remove_attachment_photo_to_course
Then open the migration file
class RemoveAttachmentPhotoToCourse < ActiveRecord::Migration
def change
remove_attachment :courses, :photo
end
end
Then run, to update the table
rake db:migrate
Where:
photo is the name of paperclip attachment you want to remove
courses is the name of table name
I have created a migration file and change the content to:
class RemoveAttachmentHrefToPortfolios < ActiveRecord::Migration
def self.up
remove_attachment :portfolios, :href
end
def self.down
remove_attachment :portfolios, :href
end
end
The problem is it is not the elegant and correct way to do it. I hope someone can improve this answer..
Normally for a migration you run rake db:rollback. Since this was a generator, you can just manually edit the table and drop the columns.
alter table portfolio drop column href_content_type;
alter table portfolio drop column href_file_name;
-- ... etc for each of the Paperclip columns.
You could also create a migration to drop the columns, but that would be overkill unless your whole team also ran the generator or you checked in schema.rb and others ran it also.
Here is an example migration for removing columns:
class RemoveMagazineFromBooks < ActiveRecord::Migration
def change
# This is not used ANYWHERE...
if column_exists? :refinery_books, :magazine
remove_column :refinery_books, :magazine
remove_index :refinery_books, :magazine if index_exists? :refinery_books, :magazine
end
end
end
Notice the test to check if the column is there. Some people may not have run the previous migration and will not have the column.
This comes from the Paperclip documentation:
remove_attachment :portfolios, :href
This will rollback the latest changes to the DB schema:
rake db:rollback
After that, simply delete the migration file.
This is presuming that you didn't commit any of the changes/migrations to a shared repository.
$ rails generate migration RemoveColumnsFromModel portfolio href
should make you a migration that will remove two columns "href" and "portfolio" from some model's table. The migration will look something like:
class RemoveColumnsFromUser < ActiveRecord::Migration
def change
remove_column :users, :foo, :string
remove_column :users, :bar, :string
end
end
Hi guys I would like to know if there's a way not to lose the data if you're trying to rollback your migration just to update the schema ? For example after running rake db:migrate, and after few rounds of data inserted, you want to add in a new attribute to the schema.
So my question is how can i add the new attribute without losing my previous record ? is it possible to do so ? Because all this while i just did by running rake db:rollback STEP= ... and lost all the data i've generated. Just wondering.
Thanks for helping
From:
BC2
if you have an existing table and want to add new attribute in existing table then simple write stand alone migration.
for ex: you have a students table with attribute name, roll_no ... and now u want to add 'address' attribute in students table
$ rails generate migration AddAddressToStudents address:string
will generate
class AddAddressToStudents < ActiveRecord::Migration
def change
add_column :students, :address, :string
end
end
then simply run "rake db:migrate"
You don't need to rollback to update the schema. Just write a new migration to update the existing table.
For example, to add a field to your user table without destroying anything, write a migration like:
class AddFieldsToUser < ActiveRecord::Migration
def change
change_table :users do |t|
t.date :birthday # add new field
t.remove :first # remove a field
t.rename :gender, :sex # rename a field
end
end
end
See here for more info: http://guides.rubyonrails.org/migrations.html#changing-tables
I have looked through many SO and google posts for generating migration of join table for has many and belongs to many association and nothing work.
All of the solutions are generating a empty migration file.
I am using rails 3.2.13 and I have two tables: security_users and assignments. These are some of things I have try:
rails generate migration assignments_security_users
rails generate migration create_assignments_security_users
rails generate migration create_assignments_security_users_join_table
rails g migration create_join_table :products, :categories (following the official documentation)
rails generate migration security_users_assignments security_user:belongs_to assignments:belongs_to
Can anyone tell how to create a join table migration between two tables?
To autopopulate the create_join_table command in the command line, it should look like this:
rails g migration CreateJoinTableProductsSuppliers products suppliers
For a Product model and a Supplier model. Rails will create a table titled "products_suppliers". Note the pluralization.
(Side note that generation command can be shortened to just g)
Run this command to generate the empty migration file (it is not automatically populated, you need to populate it yourself):
rails generate migration assignments_security_users
Open up the generated migration file and add this code:
class AssignmentsSecurityUsers < ActiveRecord::Migration
def change
create_table :assignments_security_users, :id => false do |t|
t.integer :assignment_id
t.integer :security_user_id
end
end
end
Then run rake db:migrate from your terminal. I created a quiz on many_to_many relationships with a simple example that might help you.
I usually like to have the "model" file as well when I create the join table. Therefore I do.
rails g model AssignmentSecurityUser assignments_security:references user:references
There's embeded generation for join table in rails
rails g migration AddCityWorkerJoinTable cities:uniq workers
which generates following migration
create_join_table :cities, :workers do |t|
t.index [:city_id, :worker_id], unique: true
end
❗️ NOTE:
models names should go in alphabet order
put :uniq only on first param
I believe this would be an updated answer for rails 5
create_table :join_table_name do |t|
t.references :table_name, foreign_key: true
t.references :other_table_name, foreign_key: true
end
I'm wondering how I can add associations to my models. Suppose, I generate two models
rails generate model User
rails generate model Car
Now I want to add an associations so that the models acquire the form
class User < ActiveRecord::Base
has_many :cars
end
class Car < ActiveRecord::Base
belongs_to :user
end
The question is: how to apply this modification by migrations in order to obtain cars_users table in the database? I'm planning to use that table in my code.
belongs_to association expect an association_id column in its corresponding table. Since cars belongs_to user, the cars table should have a user_id column. This can be accomplished 2 ways.
first, you can generate the column when you create the model
rails g model car user_id:references
or just add the user_id after you create the model like Richard Brown's answer. Be careful that if you use integer instead of references, you'd have to create the index yourself.
rails g migration add_user_id_to_cars user_id:integer
then in the generated migration, add
add_index :cars, :user_id
UPDATE:
As Joseph has mentioned in the comments, the need to add the index manually has already been addressed in the current version of Rails. I think it was introduced in Rails 4. You can read more of it in the official Rails guide for migrations. The gist of it is running the following generator
bin/rails g migration add_user_to_cars user:references
will create a migration with a line similar to
add_reference :cars, :user, index: true
This will add a user_id column to the cars table and it will also mark that column to be indexed.
Following #jvnill's explanation in rails 4 (and maybe in rails 3.2 too) you can do it like this too (avoiding the id parts and remembering the exact convetions):
rails g migration AddUserToCar user:references
Which will create the following migration, taking care of both adding the column and index with all correct conventions:
class AddUserToCar < ActiveRecord::Migration
def change
add_reference :cars, :user, index: true
end
end
At the end as always run the migration:
rake db:migrate
View your schema.rb to view the new index and user_id column.
Generate a migration to create the association:
rails g migration AddUserIdToCars user_id:integer
rake db:migrate
Migration file:
class Createuser < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
end
create_table :cars do |t|
t.belongs_to :user, index: true
t.varchar(255) :model
t.varchar(255) :color
end
end
end