I am in a world of mess. I had some issues with the mailboxer gem and the tables it created in my schema, so i commented the offending attributes and reset my database. Nothing changed when I ran db:migrate, so I dropped the table, created it anew and reran the migration. The schema has not updated to reflect the attributes which had been commented out. Any ideas as to why? I now have an error message when trying to rake db:migrate which aborts and says that:
PG::UndefinedTable: ERROR: relation "roles" does not exist : ALTER TABLE "roles" DROP "user_id"
My schema has a roles table which includes the following attributes:
create_table "roles", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
I have a migration in my file which is intended to remove the user_id:
class Removeuidfromrole < ActiveRecord::Migration
def change
remove_column :roles, :user_id, :integer
end
end
I have no idea why it is aborting with an error telling me to remove the user id, when I have a migration to do just that. Further, why doesn't the schema update to reflect the recreated db?
Related
I am trying to add a new column active to my table students.
I ran rails g migration add_active_to_students active:boolean to generate this migration:
class AddActiveToStudents < ActiveRecord::Migration[5.0]
def change
add_column :students, :active, :boolean, default: true
end
end
But when I run rails db:migrate I get this error:
PG::DuplicateColumn: ERROR: column "active" of relation "students" already exists
: ALTER TABLE "students" ADD "active" boolean DEFAULT 't'`
As you can see there is not actually an active column in students:
create_table "students", force: :cascade do |t|
t.integer "club_id"
t.string "email"
t.string "address_line_1"
t.string "address_line_2"
t.string "city"
t.string "state"
t.integer "postcode"
t.string "phone1"
t.string "phone2"
t.string "first_name"
t.string "last_name"
t.date "dob"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "picture"
t.integer "payment_plan_id"
t.string "parent1"
t.string "parent2"
t.string "size"
t.text "notes"
t.index ["club_id"], name: "index_students_on_club_id", using: :btree
end
So why would I be getting this error?
I followed the steps that #demir posted and found that, yes, the column was in the database without being listed in the schema. ALTER TABLE students DROP COLUMN active did not give an error message however it also didn't remove the column.
In the end I removed it by:
Entering the console
rails console
Deleting the column
ActiveRecord::Base.connection.remove_column :students, :active
You may have added it somehow. Have you checked the PG database? Connect to the application database and see if there is an active field.
List databases
\l
Connect database
\c your_app_database_name
List table columns
\d+ students
Check active field, remove it if exist.
ALTER TABLE students DROP COLUMN active
You have this column in your DB, but it wasn't dumped to your schema.rb. Maybe a migration was stopped after it added the column, but before it wrote to schema.rb?
You can remove this column manually, running rails dbconsole and then:
ALTER TABLE students DROP COLUMN active
You can follow the above solutions i.e. drop the column from DB first and then run the migration. Most probably what has happened is, you created and run some migration but later deleted that migration file without doing a db:rollback.
One more option that you can consider is to put a conditional migration like:
class AddActiveToStudents < ActiveRecord::Migration[5.0]
def change
unless column_exists? :students, :active
add_column :students, :active, :boolean, default: true
end
end
end
In my Rails 5 application I've accidentally created a column with no data type. Database is SQLite.
create_table "students", force: :cascade do |t|
t.integer "club_id"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "picture"
t.integer "payment_plan_id"
t. "activity"
t.index ["club_id"], name: "index_students_on_club_id"
end
When I attempt rails db:rollback I get this error:
Rhys-MacBook-Pro:classmaster Rhys$ rails db:rollback == 20161011105423 AddActivitiesRefToStudents: reverting =======================
-- remove_column(:students, :activity, :reference)
rails aborted! StandardError: An error has occurred, this and all later migrations canceled: undefined method `to_sym' for nil:NilClass
I've tried running this migration:
class RemoveColumn < ActiveRecord::Migration
def up
execute "ALTER TABLE students DROP COLUMN activity";
end
end
But I think SQLite doesn't support dropping columns. Is there a fix for this?
I am assuming it is the activity column you want to drop based on it not having a type in that file, if it is a different column then just change the column name below.
What you want to do is drop a column from the table, which you absolutely can do. In the command line do something like the line below (or exactly like the line below) to create the migration to drop the column.
rails g migration drop_activity_column_from_students
Then open that file, the method inside should be this.
def change
remove_column :students, :activity
end
Then run
rake db:migrate
and you should see that one column get dropped from the table.
You can find a ton of information here about migrations, if that is something you want to learn more about.
I had the same problem, and after trying various migrations and running rails db:reset without success, I just deleted my schema.rb file and ran rails db:migrate, which rebuilt my schema from scratch without the column that didn't have a data type. Just make sure that none of your migrations contain the addition of the "activity" column, so you don't repeat the problem.
Try to change the type of the column by:
rails g migration FixActivityTypeStudents
Then on the migration add this part.
def change
change_column :students, : activity, :string
end
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.
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.
I have a sqlite3 db in a rails app with the following schema
ActiveRecord::Schema.define(:version => 20100816231714) do
create_table "comments", :force => true do |t|
t.string "commenter"
t.text "body"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "posts", :force => true do |t|
t.string "name"
t.string "title"
t.text "content"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "tags", :force => true do |t|
t.string "name"
t.integer "post_id"
t.datetime "created_at"
t.datetime "updated_at"
end
end
I began with a Post :has_many relationship with tags so each tag has a post_id reference.
I now want to change this relationship to a 'has_and_belongs_to_many', I know i have to create the joins table etc.... this isn't a problem and is working
The problem comes in when i try remove the post_id form the tags table. My migration looks like this:
class RemoveFieldsToTags < ActiveRecord::Migration
def self.up
remove_column :tags, :post_id
end
def self.down
add_column :tags, :post_id, :references
end
end
When I run rake db:migrate and rake db:migrate:up VERSION= Nothing happens when I run rake db:migrate:down VERSION= I get column:
SQLite3::SQLException: duplicate column name: post_id: ALTER TABLE "tags" ADD "post_id" references
Any one know whats going on?
It sounds as if Rails thinks your DB is up to date (given that nothing happens when you run db:migrate). You can get into this state if you've modified your migration after applying it (common during development).
Have you tried running db:migrate on a fresh db (note this will wipe your database)?
rake db:drop db:create db:migrate
Like avaynshtok mentions above, it sounds like rails thinks your migrations are up to date (as in, they have all been applied), but to you they are not (the post_id column is still on the tags table).
A common 'workaround' to deal with this situation without having to wipe your database is commenting out the 'down' method of your migration and running
rake db:migrate:redo
Given the 'down' is commented out, it won't try to add the column again, so it will proceed to reapply the 'up' method, removing your 'post_id' column. You can then remove the comment on the 'down' method and it should all be good.
PS. You might want to look into using a 'has_many :through' type of relationship instead of 'has_and_belongs_to_many' as well.
I had a similar problem to the op, but had to manually delete the databases and then run
rake db:create db:migrate
rake db:migrate:redo
and
rake db:drop
did not work for me as it kept saying "db/test.sqlite3 already exists".