I've got a migration file which does the following:
class ChangeLoginToUsername < ActiveRecord::Migration
def self.up
remove_column :users, :login, :string
add_column :users, :username, :string
end
def self.down
remove_column :users, :username, :string
add_column :users, :login, :string
end
end
This ran in fine on my local dev but I've now noticed the third parameter for the filed type on remove_column is erroring when I try and run this migration on Heroku. Is there a way to write/run specific migrations just for Heroku? There are 2 further migrations after this one that I need to run...
Any help hugely appreciated as always
It doesn't make sense for remove_column to have a data type:
class ChangeLoginToUsername < ActiveRecord::Migration
def self.up
remove_column :users, :login
....
end
def self.down
remove_column :users, :username
...
end
end
Related
I'm running Rails 5.2.4.4 and have found the strangest behaviour when I have two add_references listed in my users migration. Even though they are unique lines for different table references, the output shows the first one repeated, then failing due to duplicate column. If I switch the statements around, it simply causes the other add_reference to repeat and fail:
Migration:
def change
add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :authentication_token, :string
add_column :users, :location, :string
add_column :users, :is_admin, :boolean, default: false
add_column :users, :account_active, :boolean, default: true
end
add_reference :users, :tagging, type: :uuid, foreign_key: true, null: true
add_reference :users, :tenant, type: :uuid, foreign_key: true
add_index :users, :created_at
Results in this error:
-- add_reference(:users, :tagging, {:type=>:uuid, :foreign_key=>true, :null=>true})
-- add_reference(:users, :tagging, {:type=>:uuid, :foreign_key=>true, :null=>true})
rails aborted!
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR: column "tagging_id" of relation "users" already exists
If I switch the add_references columns around:
add_reference :users, :tenant, type: :uuid, foreign_key: true
add_reference :users, :tagging, type: :uuid, foreign_key: true, null: true
I instead get:
-- add_reference(:users, :tenant, {:type=>:uuid, :foreign_key=>true})
-- add_reference(:users, :tenant, {:type=>:uuid, :foreign_key=>true})
rails aborted!
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR: column "tenant_id" of relation "users" already exists
Thanks in advance.
Found the issue...
I had placed the add_references code outside the def change block.
Shifted it and all fixed.
I've searched several questions about migrations and their answers, but I didn't find a satisfactory solution.
I want to use simple has_many and belongs_to relationships like
class User < ActiveRecord::Base
has_many :posts
has_many :comments
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
Is there any possibility to create database level constraints inside of the migration such as
post_id integer REFERENCES posts
or will I have to do this manually? At best I'd prefer a database-independent solution. Thanks in advance!
Edit: I'm currently using Postgresql, but I like to be flexible in regards of the underlying database.
Update: For the sake of database-independent code I stick with the following migration at the moment:
class AddRelations < ActiveRecord::Migration
def self.up
add_column :posts, :user_id, :integer, :null => false
add_column :comments, :user_id, :integer, :null => false
add_column :comments, :post_id, :integer, :null => false
end
def self.down
remove_column :posts, :user_id
remove_column :comments, :user_id
remove_column :comments, :post_id
end
end
I still hope to find a more elegant solution. Maybe there's a gem for that.
Use the excellent foreigner gem to add the foreign keys in your migration:
add_foreign_key :posts, :users
add_foreign_key :comments, :users
add_foreign_key :comments :posts
I installed Devise, raked, and then realized afterwards, that I want to add :confirmable.
Can I go back to the same initial migration and just uncomment out the helper that I want and then rake db:migrate again?
I tried it and it didn't seem to work. But I haven't seen an example of how to create a follow-on migration.
Thanks!
This is what I tried:
1 class AddConfirmableToUsers < ActiveRecord::Migration
2 def self.up
3 change_table :users do |t|
4 t.confirmable
5 end
6 add_index :users, :confirmation_token, :unique => true
7 end
8
9 def self.down
10 remove_column :users, :confirmation_token
11 end
12
13 end
You can add the proper columns yourself like so:
class AddConfirmableToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
end
add_index :users, :confirmation_token, :unique => true
end
def self.down
change_table :users do |t|
t.remove :confirmation_token, :confirmed_at, :confirmation_sent_at
end
remove_index :users, :confirmation_token
end
end
Your migration should work. Did you check your User model to make sure :confirmable is enabled? It's commented out by default.
If you don't mind losing your data you can just do
> rake db:drop
Otherwise you can just edit the initial migration and do a rollback.
# get the current migration version
> rake db:version
> Current version: ****************41
> rake db:rollback ****************40
Make your changes
> rake db:migrate
I've just installed the Paperclip and trying to attach an icon to my model.
has_attached_file :icon,
:styles => { :normal => "100x100>", :format => 'png' },
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:url => "/icon/:slug.:extension"
:path => "icon/:slug.:extension"
s3.yml contains my bucket name and two keys.
slug interpolation is defined in the config/initializers/paperclip.rb as
Paperclip.interpolates('slug') do |attachment, style|
attachment.instance.cached_slug
end
When I call game.icon.url, I get this error:
undefined method `icon_file_name' for #<Game:0x4000f50>
What am I doing wrong?
I'm running rails 3.0.4 and ruby 1.9.2 on Windows 7 x64, if it makes any difference.
Did you create a migration for your Game model to add in the appropriate fields that Paperclip needs? From the Paperclip documentation on Github:
class AddAvatarColumnsToUser < ActiveRecord::Migration
def self.up
add_column :users, :avatar_file_name, :string
add_column :users, :avatar_content_type, :string
add_column :users, :avatar_file_size, :integer
add_column :users, :avatar_updated_at, :datetime
end
def self.down
remove_column :users, :avatar_file_name
remove_column :users, :avatar_content_type
remove_column :users, :avatar_file_size
remove_column :users, :avatar_updated_at
end
end
After you've created that migration, you need to run the rake task to update your db: rake db:migrate
You can simply run - rails generate paperclip game icon
and it will generate the migration for you.
I made the same mistake, forgot to add the database migrations.
Here is a great article on doing this
even though it is on Heroku.
You can run the migrations like so
Create the migration file
rails g migration AddAvatarToUser
Then edit the file to the following
class AddAvatarToUser < ActiveRecord::Migration
def self.up
add_attachment :users, :avatar
end
def self.down
remove_attachment :users, :avatar
end
end
I had a similar problem, but it was working when I ran it in the browser, yet some of my tests were failing. You helped me realize that I had migrated my main development database, but I had failed to do a rake db:migrate test. Once I did that - problem disappeared.
I'm trying to run the following migration
def self.up
add_column :users, :perishable_token, :string
User.all.each { |u| u.reset_perishable_token! }
change_column :users, :perishable_token, :string, :null => false
add_index :users, :perishable_token
end
and the u.reset_perishable_token! code behaves strangely (no return value, doesn't change the database field). Consequently change_column ..., :null => false fails with
users.perishable_token may not be NULL
Even separating the migration into two doesn't do the trick either if I run them with just one rake command.
Part One
def self.up
add_column :users, :perishable_token, :string
add_index :users, :perishable_token
end
Part Two
def self.up
User.all.each { |u| u.reset_perishable_token! }
change_column :users, :perishable_token, :string, :null => false
end
Only if I run the first and second migration in separate rake processes everything runs fine.
What could possibly be the reason and how can I fix it?
I think you need to add...
User.reset_column_information
...after you have added the perishable_token to the users_table, otherwise the User model is out of sync with the database.
I think the User model would only be loaded once per 'rake db:migrate', so it wouldn't help to split the migration in two.