How to reverse an extend migration - ruby-on-rails

I recently ran this migration while installing the fuzzily gem:
class AddTrigramsModel < ActiveRecord::Migration
extend Fuzzily::Migration
end
From looking at my schema.rb file, it looks like the effect of this migration was:
create_table "trigrams", :force => true do |t|
t.string "trigram", :limit => 3
t.integer "score", :limit => 2
t.integer "owner_id"
t.string "owner_type"
t.string "fuzzy_field"
end
add_index "trigrams", ["owner_id", "owner_type", "fuzzy_field", "trigram", "score"], :name => "index_for_match"
add_index "trigrams", ["owner_id", "owner_type"], :name => "index_by_owner"
Not sure if the easiest way is just to drop the table trigrams, or if there is a more appropriate method? I am assuming the indexes will be deleted on dropping the table?

Just run rake db:rollback. Fuzzily has support for rollbacks. Although everything it does is dropping the trigrams table :)
# lib/fuzzily/migration.rb:33
def down
drop_table trigrams_table_name
end

Related

Problems setting a custom primary key in a Rails 4 migration

I use postgresql 9.3, Ruby 2.0, Rails 4.0.0.
After reading numerous questions on SO regarding setting the Primary key on a table, I generated and added the following migration:
class CreateShareholders < ActiveRecord::Migration
def change
create_table :shareholders, { id: false, primary_key: :uid } do |t|
t.integer :uid, limit: 8
t.string :name
t.integer :shares
t.timestamps
end
end
end
I also added self.primary_key = "uid" to my model.
The migration runs successfully, but when I connect to the DB using pgAdmin III I see that the uid column is not set as primary key. What am I missing?
Take a look at this answer. Try to execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);" without specifying primary_key parameter in create_table block.
I suggest to write your migration like this (so you could rollback normally):
class CreateShareholders < ActiveRecord::Migration
def up
create_table :shareholders, id: false do |t|
t.integer :uid, limit: 8
t.string :name
t.integer :shares
t.timestamps
end
execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);"
end
def down
drop_table :shareholders
end
end
UPD: There is natural way (found here), but only with int4 type:
class CreateShareholders < ActiveRecord::Migration
def change
create_table :shareholders, id: false do |t|
t.primary_key :uid
t.string :name
t.integer :shares
t.timestamps
end
end
end
In my environment(activerecord 3.2.19 and postgres 9.3.1),
:id => true, :primary_key => "columname"
creates a primary key successfully but instead of specifying ":limit => 8" the column' type is int4!
create_table :m_check_pattern, :primary_key => "checkpatternid" do |t|
t.integer :checkpatternid, :limit => 8, :null => false
end
Sorry for the incomplete info.
I have created migrations like this:
class CreateShareholders < ActiveRecord::Migration
def change
create_table :shareholders, id: false do |t|
t.integer :uid, primary_key: true
t.string :name
t.integer :shares
t.timestamps
end
end
end

Postgres error when I try to run heroku run rake db:migrate

My sqlite3 database works fine in development but when I try to migrate it to production I get the following error:
PG::Error: ERROR: relation "movies" does not exist
: ALTER TABLE "movies" ADD COLUMN "production_company" character varying(255)/app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `async_exec'
I know a few people have posted about this but nothing I've tried seems to work. Anyone know how I might fix this?
Here's the migration:
class AddProductionCompanyToMovies < ActiveRecord::Migration
def change
add_column :movies, :production_company, :string, :limit => nil
end
end
Here's my schema.rb file if this helps:
ActiveRecord::Schema.define(:version => 20130331014529) do
create_table "movies", :force => true do |t|
t.string "title"
t.string "actor_1"
t.string "locations"
t.string "release_year"
t.string "string"
t.string "actor_2"
t.string "actor_3"
t.string "writer"
t.string "director"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "production_company"
t.string "distributor"
t.string "fun_facts"
end
end
Here's the migration where I create the movies table:
class Movies < ActiveRecord::Migration
def up
end
def down
end
end
It's not the best approach but a quick fix would be to replace that migration with this:
class AddProductionCompanyToMovies < ActiveRecord::Migration
def change
create_table :movies do |t|
t.string :production_company
t.timestamps
end
end
end
Your migration where you create the movie table is incorrect. The up and down methods you have don't do anything. Because of this, there is no movie table to add the production_company column to.
You need something like this;
class Movies < ActiveRecord::Migration
def change
create_table :movies do |t|
t.string :title
t.string :actor
.
. #add your columns you want in your initial migration here
.
end
end
I can't say why things worked in development in SQLite but at some point you successfully created the movies table and then maybe you altered the migration after that. This is easy to do (I've done it!).
A lot of people recommend that when you set up production you don't run your migrations to set up the database, but instead use rake db:schema:load (in fact, if you read the comments at the top of your db/schema.rb file it specifically describes this).
Another point is that a lot of people recommend having the same database in development as in production as there are subtle differences that can lead to unexpected problems in production (this is not what has caused your issue). If you're only just starting out then don't worry about it for now; it's just one more headache to set up PostgreSQL on your own machine; but it's something to keep in mind as you progress.

t.references in Rails migration (n | n relationship)

I have three models in my Rails 3 application, DailyData and DailyDataVehicle and Vehicle, a many to many relationship.
I just learned that if you update the model with the associations, that it doesn't update the database, so I am going back and adding those migrations. I am also lucky enough to confidently think I know the differences between belongs_to and has_many, however, in my migration file, I am not sure that t.references does.
So I named the migration model AddDailyDataToDailyDataVehicle, and want to add the dailyData_id to the daily_data_vehicles table. This is a many to many relationship, so I want the id key to be in the relationship table DailyDataVehicles, but I'm not quite sure that t.references will know that.
Maybe I am slightly mixing up the class associations and the database relationships, and if I am, then please clarify this.
If t.references is not what I want, do I have to declare the relationship manually with has_many, and if so, what is the syntax for that?
schema file currently:
create_table "daily_data_vehicles", :force => true do |t|
t.integer "vehicle_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "daily_data_vehicles", ["vehicle_id"], :name => "index_daily_data_vehicles_on_vehicle_id"
Migration (attempt):
class AddDailyDataToDailyDataVehicle < ActiveRecord::Migration
def change
change_table :dailyDataVehicles do |t|
t.references :dailyData
end
add_index :dailyDataVehicles, :dailyData_id
end
end
What I think the schema file should look like if the migration works correctly:
create_table "daily_data_vehicles", :force => true do |t|
t.integer "vehicle_id"
t.integer "dailyData_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "daily_data_vehicles", ["vehicle_id"], :name => "index_daily_data_vehicles_on_vehicle_id"
add_index "daily_data_vehicles", ["dailyData_id"], :name => "index_daily_data_vehicles_on_daily_data_id"
with the difference being t.integer "dailyData_id" and add_index "daily_data_vehicles", ["dailyData_id"], :name => "index_daily_data_vehicles_on_daily_data_id"
class AddDailyDataToDailyDataVehicle < ActiveRecord::Migration
def change
add_column :daily_data_vehicles, : daily_data_id, :integer
add_index :daily_data_vehicles, :daily_data_id
end
end
class DailyDataVehicle < ActiveRecord::Base
belongs_to :daily_data
end
class DailyData < ActiveRecord::Base
has_many :daily_data_vehicles
end

Why do created_at/updated_at get created when migration does not have timestamps?

I'm using rails 3.2 with the following migration and created_at/updated_at both get generated. I was under the impression that adding t.timestamps was what caused those columns to get generated.
class CreateContactsCountries < ActiveRecord::Migration
def change
create_table :contacts_countries do |t|
t.string :name, :official_name, :null => false
t.string :alpha_2_code, :null => false, :limit => 2
t.string :alpha_3_code, :null => false, :limit => 3
end
add_index :contacts_countries, :alpha_2_code
end
end
Please delete the table and check again becuase
By default, the generated migration will include t.timestamps (which creates
the updated_at and created_at columns that are automatically populated
by Active Record).
Ref this

Index name is too long - Rails 3

I am trying to run this migration:
class RemoveClientFromSalesteam < ActiveRecord::Migration
change_table :sales_teams do |t|
t.remove :client_id
end
end
This is the error I am getting:
rake db:migrate
-- change_table(:sales_teams)
rake aborted!
An error has occurred, this and all later migrations canceled:
Index name 'temp_index_altered_sales_teams_on_client_priority_and_personal_priority' on table 'altered_sales_teams' is too long; the limit is 64 characters
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
This is what my schema.rb looks like:
create_table "sales_teams", :force => true do |t|
t.string "name"
t.integer "firm_id"
t.boolean "client_priority"
t.boolean "personal_priority"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "client_id"
end
add_index "sales_teams", ["client_id"], :name => "index_sales_teams_on_client_id"
add_index "sales_teams", ["client_priority", "personal_priority"], :name => "index_sales_teams_on_client_priority_and_personal_priority"
add_index "sales_teams", ["name", "firm_id"], :name => "index_sales_teams_on_name_and_firm_id"
Thoughts?
Thanks.
Drop the index, remove your column, and then re-add the index:
def up
remove_index :sales_teams, :column => [ :client_priority, :personal_priority ]
remove_column :sales_teams, :client_id
add_index :sales_teams, [ :client_priority, :personal_priority ]
end
I'm guessing that you're using SQLite, most databases support real ALTER TABLE operations for removing columns but SQLite forces you to copy the table (and indexes), drop the table, and copy everything back; the Rails SQLite driver takes care of this behind the scenes but, apparently, doesn't know about the identifier length limit.
You can also specify your own index names by using the :name option to add_index and remove_index if necessary.

Resources