I ran rake db:loadschema by accident last night when i was trying to edit some of my migrations to push the app up on heroku.
The admin user was working perfectly for 'admin#gmail.com'
now when i rake db:migrate my migrations again i get an error
== 20150404180803 UpdateUsers: migrating ======================================
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
undefined method `update_attributes' for nil:NilClass/home/ubuntu/workspace/hrApp/db/migrate/20150404180803_update_users.rb:7:in `change'
/usr/local/rvm/gems/ruby-2.1.5#rails4/gems/activerecord-4.2.0/lib/active_record/migration.rb:606:in `exec_migration'
/usr/local/rvm/gems/ruby-2.1.5#rails4/gems/activerecord-4.2.0/lib/active_record/migration.rb:590:in `block (2 levels) in migrate'
class AddAdminToUsers < ActiveRecord::Migration
def change
add_column :users, :admin, :boolean, :default => false
end
end
class UpdateUsers < ActiveRecord::Migration
def change
#u = User.find_by( email: 'admin#gmail.com')
#u.update_attribute :admin , true
##u.update_attributes(:admin ,true)
end
end
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
Anyone any ideas on whats causing this error?
Thanks infused. Ive tried putting into the user model
#u = User.new(:email => "admin#gmail.com")
#u.save
gettin an error
rake aborted!
ActiveRecord::StatementInvalid: Could not find table 'users'
/usr/local/rvm/gems/ruby-2.1.5#rails4/gems/activerecord-4.2.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:517:in `table_structure'
sorry should be
#u = User.new(email: 'admin#gmail.com')
#u.save
get the error
rake aborted!
ActiveRecord::StatementInvalid: Could not find table 'users'
/usr/local/rvm/gems/ruby-2.1.5#rails4/gems/activerecord-4.2.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:517:in `table_structure'
/usr/local/rvm/gems/ruby-2.1.5#rails4/gems/activerecord-4.2.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:389:in `columns'
The migration expects there to be a user in the database with an email address of 'admin#gmail.com':
#u = User.find_by( email: 'admin#gmail.com')
#u.update_attribute :admin , true
If that user does not exist, then #u will be nil and you'll get the error you're seeing. Add a record for that user to the database and then re-run the migrations.
Related
here's my current user schema:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# first_name :string
# last_name :string
# created_at :datetime not null
# updated_at :datetime not null
#
require 'elasticsearch/model'
class User < ActiveRecord::Base
searchkick word_start: [:user]
has_many :posts
validates :first_name, :last_name, presence: true
end
these are the steps I'm able to go through before the problem rears its head:
rails generate devise:install
rails generate devise user
rake db:migrate
once i try to migrate it, this is what comes up:
== 20160707230510 AddDeviseToUsers: migrating =================================
-- change_table(:users)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DuplicateColumn: ERROR: column "email" of relation "users" already exists
: ALTER TABLE "users" ADD "email" character varying DEFAULT '' NOT NULL
/Users/aa/Documents/railsy/basicProject/db/migrate/20160707230510_add_devise_to_users.rb:5:in `block in up'
/Users/aa/Documents/railsy/basicProject/db/migrate/20160707230510_add_devise_to_users.rb:3:in `up'
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR: column "email" of relation "users" already exists
: ALTER TABLE "users" ADD "email" character varying DEFAULT '' NOT NULL
/Users/aa/Documents/railsy/basicProject/db/migrate/20160707230510_add_devise_to_users.rb:5:in `block in up'
/Users/aa/Documents/railsy/basicProject/db/migrate/20160707230510_add_devise_to_users.rb:3:in `up'
PG::DuplicateColumn: ERROR: column "email" of relation "users" already exists
/Users/aa/Documents/railsy/basicProject/db/migrate/20160707230510_add_devise_to_users.rb:5:in `block in up'
/Users/aa/Documents/railsy/basicProject/db/migrate/20160707230510_add_devise_to_users.rb:3:in `up'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
as you can tell from my earlier user schema, there is no email column there. so ... why does this error come up?
**EDIT - should have posted devise migration file - the one that doesn't work **
class AddDeviseToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.inet :current_sign_in_ip
t.inet :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
# Uncomment below if timestamps were not included in your original model.
# t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
def self.down
# By default, we don't want to make any assumption about how to roll back a migration when your
# model already existed. Please edit below which fields you would like to remove in this migration.
raise ActiveRecord::IrreversibleMigration
end
end
EDIT AGAIN
when i run rails g devise user ... this is what comes up:
Running via Spring preloader in process 72318
invoke active_record
create db/migrate/20160707230510_add_devise_to_users.rb
insert app/models/user.rb
route devise_for :users
Turns out all I had to do was to do rake db:setup which recreates the db. Then I ran rake db:migrate, and no issues came up this time.
FYI. Hope this helps someone out there.
To eliminate migration errors on duplicate fields, use t.change as shown below.
t.change :email, :string, :null => false, :default => ""
Notice that for t.change to work, you have to specify the type for the field being changed. In the case of the email migration above, the email field was of type string.
You can refer at: devise wiki
So i'm having some issues with migrations in rails.. i have 2 migrations one to add the users table and one to add devise to users...
now im getting this error when i try run
rake db:migrate
ActiveRecord::StatementInvalid: SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "email" varchar DEFAULT '' NOT NULL
which tells me that both migrations are trying to add the column email to the users table..
USER TABLE CREATE MIGRATION
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.string :password_digest
t.timestamps null: false
end
end
end
DEVISE ADDED TO USERS MIGRATION
class AddDeviseToUsers < ActiveRecord::Migration
def self.up
change_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
# Uncomment below if timestamps were not included in your original model.
# t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
def self.down
# By default, we don't want to make any assumption about how to roll back a migration when your
# model already existed. Please edit below which fields you would like to remove in this migration.
raise ActiveRecord::IrreversibleMigration
end
end
im assuming its the
add_index :users, :email, unique: true
line in the 2nd migration causing this issue... but im just curious... is that line even relevant to devise? i can't find anything relating to this in the documentation... so if I were to delete those 2 lines would that have any effect on the way Devise runs??
You are trying to create column email twice: in your own migration and in devise. Also, you don't need password_digest column. Second time you got an error because the column already exists.
My advice is to rollback on version before creating users (rake db:rollback VERSION=timestamp_from_migration_filename), remove email and password_digest from your CreateUsers and try again all migrations.
change_column helper is for making multiple alteration on a single table. It always try to add column.
Please check the details on api-dock
I'm following a tutorial on adding the Devise gem to Rails. One feature of the gem is generating a "user" using Devise, for further user authentication (Facebook, Twitter, etc.). I'm running into the following error:
== 20150906025001 AddDeviseToUsers: migrating =================================
-- change_table(:users)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "email" varchar DEFAULT '' NOT
NULL/Users/jaker/.rvm/gems/ruby-2.0.0-p643/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `initialize'
I already have a User model in my app, that has an email, so this makes sense. However, when I try to run a migration and delete my "User" table, I'm still getting the same error.
[timestamp]_add_devise_to_users.rb:
class AddDeviseToUsers < ActiveRecord::Migration
def self.up
change_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
# Uncomment below if timestamps were not included in your original model.
# t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
def self.down
# By default, we don't want to make any assumption about how to roll back a migration when your
# model already existed. Please edit below which fields you would like to remove in this migration.
raise ActiveRecord::IrreversibleMigration
end
end
Does anyone know how to fix this? I'm really confused, and no documentations have seemed to help. Thanks so much.
This error is happening because you already have a column called email in your User model
You could comment (or remove) the line:
t.string :email, null: false, default: ""
and the script will continue.
I am deploying my rails 4 app on vps with ssh and when I run
bundle exec rake db:migrate RAILS_ENV=production
this is what I get:
[root#georgigeorgiev public_html]# bundle exec rake db:migrate RAILS_ENV=production
-- t()
-- t()
rake aborted!
ActiveRecord::MigrationProxy#disable_ddl_transaction delegated to migration.disable_ddl_transaction, but migration is nil: #<struct ActiveRecord::MigrationProxy name="DeviseCreateUsers", version=20140217200926, filename="/home/bboyratings/public_html/db/migrate/20140217200926_devise_create_users.rb", scope="">
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:712:in `rescue in disable_ddl_transaction'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:708:in `disable_ddl_transaction'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:1012:in `use_transaction?'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:922:in `rescue in block in migrate'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:919:in `block in migrate'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:916:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:916:in `migrate'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:764:in `up'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/migration.rb:742:in `migrate'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/gems/activerecord-4.0.0/lib/active_record/railties/databases.rake:42:in `block (2 levels) in <top (required)>'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/bin/ruby_executable_hooks:15:in `eval'
/usr/local/rvm/gems/ruby-2.0.0-p451#rails4/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
also my devise migration file:
class DeviseCreateUsers < ActiveRecord::Migration
t.has_attached_file :avatar
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
end
Thanks!
Remove
t.has_attached_file :avatar
from the migration.
If you are using Paperclip for image upload(for field avatar) then add the following line in the migration:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
...
t.attachment :avatar
...
end
...
end
end
After this perform bundle exec rake db:migrate RAILS_ENV=production
I have a devise User model which I want to add a admin boolean field so I ran
rails generate migration add_admin_to_users admin:boolean which created the following migration
class AddAdminToUsers < ActiveRecord::Migration
def change
add_column :users, :admin, :boolean
end
end
However when I run rake db:migrate I keep getting the following error
SQLite3::SQLException: no such table: users: ALTER TABLE "users" ADD "admin" boolean/home/notebook/.rvm/gems/ruby-2.0.0-p353/gems/sqlite3-1.3.8/lib/sqlite3/database.rb:91:in `initialize'
I have tried to rake db:migrate VERSION=0 to rollback to the beginning and redone rake db:migrate again but I keep getting the same error
Here is my user model migration file
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0, :null => false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
end
end
My db/schema.rb file is as follows:
ActiveRecord::Schema.define(version: 20140217093954) do
create_table "entities", force: true do |t|
t.string "entity"
t.string "genre"
t.string "url"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "entities", ["entity"], name: "index_entities_on_entity", unique: true
end
It sounds like your development database is not in sync with the schema (or what you think the schema is). Running database migrations is intended for incremental changes and not intended to be be a way to rollback the database and run from the first migration. For this you want to use rake db:reset, which will drop the database and load the schema from db/schema. This post has a good overview of the different database rake commands.
Your database has not users table, you need to create users table first:
rails g migration create_users
And put that migration before the one you are trying to run now, i.e. changing its timestamp.
An easier option is to add in your current file:
class AddAdminToUsers < ActiveRecord::Migration
def change
create_table :users
add_column :users, :admin, :boolean
end
end
Whatever of the solutions you apply, you have a problem with the order of your migrations, search inside migrate folder for a migration that actually creates users table.