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.
Related
I started to write an api in rails. I want to migrate my model to db, but I get this error:
E:\WebAuction\Backend\api>rails db:migrate
rails db:migrate
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table.
E:/WebAuction/Backend/api/db/migrate/20180516070242_create_wa_players.rb:4:in `block in change'
E:/WebAuction/Backend/api/db/migrate/20180516070242_create_wa_players.rb:3:in `change'
bin/rails:4:in `<main>'
Caused by:
ArgumentError: you can't redefine the primary key column 'id'. To define a custom primary key, pass { id: false } to create_table.
E:/WebAuction/Backend/api/db/migrate/20180516070242_create_wa_players.rb:4:in `block in change'
E:/WebAuction/Backend/api/db/migrate/20180516070242_create_wa_players.rb:3:in `change'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
== 20180516070242 CreateWaPlayers: migrating ==================================
-- create_table(:wa_players)
My Model class
class WaPlayer < ApplicationRecord::Base
has_secure_password
def change
create_table :wa_players, :id => false do |t|
t.id :String
t.playerName :String
t.uuid :String
t.password :String
t.money :String
t.itemsSold :String
t.itemsBought :String
t.earnt :String
t.spent :String
t.Permissions :String
t.Locked :String
t.timestamps null: false
end
add_index :wa_players, :id
end
end
If someone knows how to fix, please tell me how.
Don't know where you are getting your activerecord knowledge from, but you seem to have messed it up. It's not a t.<column> <type>. It is t.<type> <column>.
t.string :id
t.string :player_name
And so on.
(Note: most names in ruby follow snake_case naming convention, not camelCase).
From the content provided, it seems like you are heading the wrong way:
Firstly, generating migration for model which seems you have done it as you have shared the model class.
Model Class
class WaPlayer < ApplicationRecord::Base
has_secure_password
end
Thus, there would be migration for the same ie:
def change
create_table :wa_players, :id => false do |t|
t.id :String
t.playerName :String
t.uuid :String
t.password :String
t.money :String
t.itemsSold :String
t.itemsBought :String
t.earnt :String
t.spent :String
t.Permissions :String
t.Locked :String
t.timestamps null: false
end
add_index :wa_players, :id
end
The contents of the migration are wrong which needs to be updated with:
def change
create_table :wa_players, :id => false do |t|
t.string :id
t.string :player_name
t.string :uuid
t.string :password
t.string :money
t.string :items_sold
t.string :items_bought
t.string :earnt
t.string :spent
t.string :permissions
t.string :locked
t.timestamps null: false
end
add_index :wa_players, :id
end
Now you need to run
rake db:create
if the db has not been migrated else run
rake db:migrate.
It will be t.string then column_name like
def change
create_table :wa_players, :id => false do |t|
t.string :id
t.string :player_name
t.string :uuid
t.string :password
t.string :money
t.string :items_sold
t.string :items_bought
t.string :earnt
t.string :spent
t.string :permissions
t.string :locked
t.timestamps null: false
end
add_index :wa_players, :id, unique: true
end
Look at that Creating a Table
Update
I don't know how you trying but follow these steps
run your console like rails g model WaPlayer
Go to db/migrate/TIMESTAMP_create_wa_players.rb
Then paste this change method into class
Then run rails db:migrate or rake db:migrate after rake db:create if you did not create the DB till now
I was trying to fix a bad migration. I reset my database a couple times and it's just causing further problems, namely that not all my migrations are even running now.
Below are all the migrations, the one that was broken is the one yet to be run. But when I try to do a rake db:migrate I get this error:
undefined method `to_sym' for
nil:NilClass/usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/schema_definitions.rb:258:in
`column'
This is an issue in itself but what is most confusing to me is that the migration to create the simulation table just isn't running. My scheme looks like this:
ActiveRecord::Schema.define(version: 20150806192507) do
create_table "users", force: :cascade do |t|
t.string "email", limit: 96, default: "", null: false
t.string "encrypted_password", limit: 60, default: "", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
end
Any suggestions as to:
The simulations table is not being created when I do a reset and re-migrate.
The final migration to remove the verdict column is failing.
These are the migrations I have:
1.
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => "", limit: 96
t.string :encrypted_password, :null => false, :default => "", limit: 60
t.timestamps
t.index :email, unique: true
end
end
end
2.
class CreateSimulations < ActiveRecord::Migration
def change
# Needs the hash column worked out before this is run
create_table :simulations do |t|
t.integer :x_size
t.integer :y_size
t.string :verdict
t.string :arrangement
end
add_reference :simulations, :user, index: true
end
end
3.
class AddOpinionToSimulation < ActiveRecord::Migration
def change
add_column :simulations, :opinion, :hash
end
end
Finally, this is the bad one I was trying to run that started these problems. I have deleted the file to stop it from attempting to be migrated:
class RemoveVerdictFromSimulations < ActiveRecord::Migration
def change
remove_column :simulations, :verdict
end
end
Any suggestions?
There is no table simulations in your schema. If if it's not there, then you'll never be able to run that third migration.
First, refresh your database schema to make sure it's accurate in relation to your database with rake db:schema:dump
If there is indeed no simulations table, then first make sure that migration 2 succeeds.
Check schema_migrations table. If there are two rows there, then rails will think that the simulations table got created already, just delete the last entry from this table and migrate again making sure that the simulations table gets created this time, then try again with migration 3
My solution to this particular error was to go into my SQL database, delete every single version in the schema table. Then I did a
rake db:drop
I then walked through each version to make sure they migrated in order using:
rake db:migrate VERSION=<VERSION_NUMBER_FROM_EARLIEST_TO_LATEST>
If I ran into an error about a table not existing using:
rake db:prepare
Seemed to fix it aside from the last problem migration.
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
I just deployed a simple Ruby on Rails (3.0.10) application to Heroku. There is a line of code create a new User object like this.
User.create(:name => "[name here]", :email => "[email here]")
It can run well in my local machine, which is using MySQL. After I deployed it to Heroku, I got an error.
ActiveRecord::StatementInvalid: PGError: ERROR: null value in column "id" violates not-null constraint : INSERT INTO "users" ("id", "name", "email", "created_at", "updated_at") VALUES (NULL, '[name here]', '[email here]', '2011-09-28 03:59:12.908593', '2011-09-28 03:59:12.908593') RETURNING "id"
I have no idea what's wrong with my code. Did i miss anything?
Thanks all.
UPDATE
Migration
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :email
t.string :name
t.timestamps
end
end
def self.down
drop_table :users
end
end
Schema
ActiveRecord::Schema.define(:version => 20110922071106) do
create_table "users", :force => true do |t|
t.string "email"
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Did you do this:
(Taken from http://railsapps.github.com/rails-heroku-tutorial.html)
Replace SQLite with PostgreSQL If you are developing locally using
SQLite, you will need to switch to PostgreSQL for deployment to
Heroku. If you don’t want to develop using PostgreSQL locally, you
can set up your Gemfile to use SQLite for development and PostgreSQL
for production.
To switch from SQLite to PostgreSQL for deployment to Heroku, edit
your Gemfile and change this line:
gem 'sqlite3'
To this:
group :production do
gem 'pg'
end
group :development, :test do
gem 'sqlite3'
end
For anyone else looking, I had this same problem. Worked fine in dev, but failed in production with Postgres. The problem I had I tracked back to the CanCan plugin, specifically code I had that was creating a guest user the ability.rb file, if no user object existed. The guest account was suggested in a Railscast. I removed the User.new guest creation command and the problem resolved.
I just re-create the whole RoR application, and copy all the controllers, models, and views that I built to the new app. It is now running well.
I tried to compare 2 versions and didn't have any result. Will let you guys know if I find out the cause of this.
Thanks all. :)
I had a similar problem. if you try to reload the schema (on local, dont do it on production obviously), you should see a difference in what you think you have and what the database actually thinks.
rake db:schema:dump
rake db:schema:load
THIS WILL ERASE YOUR DATA. But you should see a difference in the schema for 'users'. This was my difference:
The fresh dump showed:
create_table "posts", :id => :false, :force => true do |t|
t.integer "id", :null => false, :limit=> 8
t.integer "object_id", :limit => 8
t.string "post_type"
t.string "from_id"
t.text "picture_url"
t.text "video_source"
t.integer "shares"
t.integer "likes"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "image_size", :limit => 8
t.integer "vid_size", :limit => 8
end
But i know that id is handled by rails and this should be:
create_table "posts", :force => true do |t|
t.integer "object_id", :limit => 8
t.string "post_type"
t.string "from_id"
t.text "picture_url"
t.text "video_source"
t.integer "shares"
t.integer "likes"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "image_size", :limit => 8
t.integer "vid_size", :limit => 8
end
If this is also the case for you, simply add to your user model:
set_primary_key :id
That reset it and it works now. I still don't know the cause of the problem but this fixed it for me.
I'm trying to heroku rake db:reset from a Rails 3 app using sqlite3, but I'm getting the following error:
rake aborted!
PGError: ERROR: type modifier is not allowed for type "text"
LINE 1: ...ary key, "name" character varying(255), "content" text(255),...
^
here is my most recent migration:
change_table :mixes do |t|
t.change :content, :text
t.change :post, :text
end
and my schema.rb:
create_table "mixes", :force => true do |t|
t.string "name"
t.text "content", :limit => 255
t.datetime "created_at"
t.datetime "updated_at"
t.string "mixologist"
t.string "link"
t.string "title"
t.text "post", :limit => 255
end
From my understanding Sqlite3 doesn't enforce limits on string and text and I didn't add those limits myself. I thought Heroku would automatically handle those in converting to Postgres or whatever it does. But it seems like the limits are throwing it off somewhere. What's the best way for me to deal with this?
Let me know if I should post anything else.
Change your recent migration to
change_table :mixes do |t|
t.change :content, :text, :limit => nil
t.change :post, :text, :limit => nil
end
This is one of the many nuances you will have to look out for when developing using sqlite3 :( Only happens when you alter the type of a column from string to text.