Custom code for a lost migration file with Rails 5 - ruby-on-rails

One of my migration file vanished to blue sky 🤷‍♂️ I'm gonna need to rewrite it manually I guess. 😰
This is what I have in schema.rb for that table
+ create_table "collections", force: :cascade do |t|
+ t.string "title"
+ t.string "description"
+ t.bigint "designer_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["designer_id"], name: "index_collections_on_designer_id"
+ end
so should my custom migration be as seen below?
def change
create_table :collections do |t|
t.string :title
t.string :description
t.integer :designer_id
t.timestamps
end
end
Should I do anything about add_index?
Thank you!
-----------
EDITED SOLUTION IDEA
Instead of creating new file, I'm going to add to an existing migration file. So that code below should do the job, right?
class AddSlugToCollections < ActiveRecord::Migration[5.1]
def change
create_table :collections do |t|
t.string :title
t.string :description
t.integer :designer_id
t.timestamps
end
add_index :collections, :designer_id
add_column :collections, :slug, :string
add_index :collections, :slug
end
end

Yes, If you want to retain same changes again then you should add index too.
change migration as,
def change
create_table :collections do |t|
t.string :title
t.string :description
t.integer :designer_id
t.timestamps
end
add_index :collections, :designer_id
end

#ganesh Navale is correct. I want to add one more point in this. If your migration is already run then rename the new migration timestamp with the old migration timestamp. You can get old migration timestamp from rake db:migrate:status command.

Related

How to make Ahoy gem tracking visits for users with uuid?

I have a User model with uuid for id column.
Ahoy gem creates visits as expected but the user_id is wrong.
Any ideas?
ok. Got that. Ahoy gem doesn't work with user_id as UUID. It takes the first digits from uuid and stores that in user_id for Ahoy::Visit which could look like random value.
The solution is to change the user_id type to uuid.
This migration would do the trick:
class ChangeAhoyVisits < ActiveRecord::Migration[5.2]
def change
Ahoy::Visit.destroy_all
remove_column :ahoy_visits, :user_id, :bigint
add_column :ahoy_visits, :user_id, :uuid, foreign_key: true, null: true
add_index :ahoy_visits, :user_id
end
end
Probably need to add the same type: :uuid to the user_id column in the ahoy_events table as well. After a few rake db:rollback's I ended up modifying the original migration file that is created by rails generate ahoy:install to look like this before I ran the migration:
def change
create_table :ahoy_visits do |t|
t.string :visit_token
t.string :visitor_token
# the rest are recommended but optional
# simply remove any you don't want
# user
t.references :user, type: :uuid, foreign_key: true, index: true
# standard
t.string :ip
t.text :user_agent
t.text :referrer
t.string :referring_domain
t.text :landing_page
# technology
t.string :browser
t.string :os
t.string :device_type
# location
t.string :country
t.string :region
t.string :city
t.float :latitude
t.float :longitude
# utm parameters
t.string :utm_source
t.string :utm_medium
t.string :utm_term
t.string :utm_content
t.string :utm_campaign
# native apps
t.string :app_version
t.string :os_version
t.string :platform
t.datetime :started_at
end
add_index :ahoy_visits, :visit_token, unique: true
create_table :ahoy_events do |t|
t.references :visit
t.references :user, type: :uuid, foreign_key: true, index: true
t.string :name
t.jsonb :properties
t.datetime :time
end
add_index :ahoy_events, [:name, :time]
add_index :ahoy_events, :properties, using: :gin, opclass: :jsonb_path_ops
end
And after running this slightly modified migration rather than original everything seemed to populate properly on an 'ahoy.track' in the db.

When I run rails db:migrate the migration doesn't fully work

class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.text :body
t.integer :user_id
t.timestamps
end
end
end
After running rails db:migrate my schema looks like this...
ActiveRecord::Schema.define(version: 2020_03_20_063104) do
create_table "messages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "username"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
I am wondering where the t.text "body" is and where the t.integer "user_id"is and why it isn't showing up in my schema under messages table.
I have checked migration status and all migrations have been ran.
If you ran something like this in your migration file
class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.timestamps
end
end
end
Messages table is created and after this you can't create another migration with create_table :messages. Like #Marek Lipka wrote on comments. Either you need to rollback your CreateMessages migration and chance file and run your migration again. Or you need to write another migration to change existing table like this.
class AddBodyAndUserIdToMessages < ActiveRecord::Migration[5.2]
def change
add_column :messages, :body, :text
add_column :messages, :user_id, :integer
end
end

Rails schema not changing

I'm trying to change a column called "description" in my table called "posts" to a .text rather than a .string so I can avoid getting errors for the value being too long.
I generated a new migration and ran rake db:migrate after having this:
class ChangePostsFormatInMyTable < ActiveRecord::Migration
def self.up
change_column :posts, :description, :text, :limit => nil
end
def self.down
change_column :posts, :description, :string
end
end
But the schema file doesn't show any changes and my column won't change. Am I missing something?
Schema:
ActiveRecord::Schema.define(version: 20140125221803) do
create_table "posts", force: true do |t|
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "title"
t.string "image"
end
end

How to set primary key in ruby on rails migration?

How can I set primary key for my IdClient field? I have tried all methods, but I'll get errors (rails 3.0.9)... Could you help me?
class CreateCustomers < ActiveRecord::Migration
def self.up
create_table :customers do |t|
t.integer :IdCustomer
t.string :username
t.string :crypted_password
t.string :password_salt
t.string :persistence_token
t.string :email
t.string :Skype
t.string :ICQ
t.string :Firstname
t.string :Lastname
t.string :Country
t.string :State
t.string :City
t.string :Street
t.string :Building
t.integer :Room
t.string :AddressNote
t.date :DateOfReg
t.integer :CustGroup
t.float :TotalBuy
t.timestamps
add_index(:customers, :IdCustomer, :unique => true)
end
end
def self.down
drop_table :customers
end
end
Also how to set relations in model?
Don't do this. Use the built-in id field as the primary key. If you're going to use Rails, you should build your app the "Rails way" unless you have very good reason not to.
If you really want to do this, you can pass a :primary_key option to create_table:
create_table :customers, :primary_key => :idClient do |t|
# ...
end
You'll also need to tell your model the name of its primary key via self.primary_key = "idClient"

rails 3.2 migration cannot add index to create_table in change method

here is my migration in rails 3.2.2:
class CreateStatistics < ActiveRecord::Migration
def change
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
t.index [:name, :item_id]
end
end
end
and here is the migrate error:
== CreateStatistics: migrating ===============================================
-- create_table(:statistics)
ActiveRecord::ConnectionAdapters::TableDefinition
rake aborted!
An error has occurred, all later migrations canceled:
undefined method `index' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0xbd16888>
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
what is the right way to create a index?
You can still add an index as a part of a "change" migration. You just have to do it outside of the call to create_table:
class CreateStatistics < ActiveRecord::Migration
def change
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, [:name, :item_id]
end
end
This correctly creates the table and then the index on an "up" migration and drops the index and then the table on a "down" migration.
so I change it to the old way, and it works.
and I think there is a new way doing this by using change method.
class CreateStatistics < ActiveRecord::Migration
def up
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, [:name, :item_id]
end
def down
drop_table :statistics
end
end
If you have more than one index and don't want to repeat the table name several times in individual add_index calls, you can use a change_table block that follows the create_table.
create_table :user_states do |t|
t.references :user, :null => false
t.integer :rank
t.integer :status_code
end
change_table :user_states do |t|
t.index [:rank, :status_code]
end
class CreateTempPfp < ActiveRecord::Migration
def change
create_table :temp_ptps do |t|
t.string :owner
t.integer :source_id
t.string :source_type
t.integer :year
t.string :pcb_type
t.float :january
t.float :february
t.float :march
t.float :april
t.float :may
t.float :june
t.float :july
t.float :august
t.float :september
t.float :october
t.float :november
t.float :december
t.float :dollar_per_sqft
t.float :dollar_per_unit
t.integer :rp_acc_code
t.integer :rp_property_id
t.integer :real_estate_property_id
t.timestamps
end
add_index :temp_ptps, [:source_id, :source_type]
end
end
It looks like create_table yields an ActiveRecord::ConnectionAdapters::TableDefinition class. This class does not contain the method index. Instead, change_table appears to yield an ActiveRecord::ConnectionAdapters::Table class which includes this index method.
If you want to add an index during a create_table migration, try this:
class CreateStatistics < ActiveRecord::Migration
def self.up
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, :name
add_index :statistics, :item_id
end
def self.down
drop_table :statistics
end
end

Resources