I know this question has been asked before but none of the answers helped me.
I have the following situation.
I installed devise (all worked well)
Want to include a confirmation mail, so I do
Included :confirmable in the user model
Uncommented the relevant lines in my migrate file (see my whole file below).
Run rake db:migrate (and restarted server)
When I try to sign up now however, I get ""
undefined local variable or method `confirmed_at' for X....
What am I missing here?
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
# t.string :name
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
You say, you changed your migration and rerun rake db:migrate.
It's not a good idea to change migrations, that had already been migrated.
Rails does not reconise changes in migrations. So unless you really know, that your last migration is not deployed or checked in yet and all data in your current table can be discarted don't change migrations.
Instead create a new migration that adds the new fields.
If you really know, what you are doing, you can roll back the last (or even a view) migration(s), change it and then run it again:
rake db:rollback STEP=1
# edit your migration
rake db:migrate
Related
I keep getting this error when I try to run my application. It states that there is an undefined method error in the application, but doesn't state where. The closest error I could find as tangible was this:
NameError (undefined local variable or method `confirmed_at' for #<User:0x6049800>):
I'm not sure which part this is directing to. Could someone please tell me what this error means?
This is the code for the devise_users file
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :name, null: false, default: ""
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.string :about
t.string :avatar
t.string :cover
## 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
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.timestamps null: false
## 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 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, :confirmation_token, unique: true
add_index :users, :unlock_token, unique: true
end
end
There are not any other places within the application where the method is called, therefore the error states that the method is being called somewhere when it isn't. How can I fix this error?
Your migration file DeviseCreateUsers created a table users in the database, and one of the columns in that table is confirmed_at.
In your app/models/user.rb file you probably declared your devise configuration like:
class User < ActiveRecord::Base
devise :registerable, :confirmable
...
end
ActiveRecord::Base, the class User is inheriting from, automatically creates "getter" and "setter" methods for database columns (i.e. confirmed_at), so the method #confirmed_at should already be defined.
So if the method is "missing", you may not have run the database migrations (e.g. rake db:migrate)
Search your code for confirmed_at -- it seems you used it somewhere without defining it first.
It would be nice if the error message gave you a file name and a line number, but (depending on which text editor or IDE you're using) you might be able to run a search on the entire Rails app at once.
My guess is you called the confirmed_at method on a user object (user_1.confirmed_at, for example) and the method wasn't defined in class User.
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 create a user model via command rails generate devise Users.
I want my Users model to stay the same however I want to add more columns but I'm not sure how and I am still a bit confused at the moment. I am pretty new to Ruby on Rails. I am not sure what command I am supposed you run after these changes are made as well. I think it is rake db:migrate in order to update the database.
I want to be able to add
name - string
address - string
username - string ..
According to this example in the documentation,
class AddDetailsToProducts < ActiveRecord::Migration
def change
add_column :products, :part_number, :string
add_column :products, :price, :decimal
end
end
Inside the change method, add columns part_number (string) and price (decimal) to the products table
Would this
file: 20141011161019_devise_create_users.rb
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.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
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
First, run rake db:migrate. This will run the migration prepared by devise on your database.
After that, just add more fields to your model, just the same as you would if you'd never installed devise. The first step is to generate a new migration. Run this at the command line:
bin/rails generate migration AddNameAddressUsernameToUsers name:string address:string username:string
This will create a new migration file. You should then run that migration file on your database, with rake db:migrate again. After that, you should be able to refer to those new model fields in your controller and views.
While you could do it all in a single migration, it's generally better to keep your migrations small and discrete. This makes it easier to resolve issues if anything goes wrong.
Don't change the existing migration. You want to create a new migration with the command rails generate migration MigrationName, and then follow the Active Record Migrations Rails Guide, which gives lots of examples on how to add database columns.
I am wondering how can i add devise to an existing database with a different user. Here I already have a customer model define and I want to change to allow devise to work on it.
I have created a new migration and inserted the code has follow
class AddDeviseToCustomer < ActiveRecord::Migration
def change
change_table :customers do |t|
#t.database_authenticatable
t.string :encrypted_password, :null => false, :default => '', :limit => 128
t.confirmable
t.recoverable
t.rememberable
t.trackable
t.token_authenticatable
t.timestamps
end
end
end
According to this it should work. https://github.com/plataformatec/devise/wiki/How-To:-change-an-already-existing-table-to-add-devise-required-columns. But when running rake db:migrate i get the following
undefined method `confirmable' for #<ActiveRecord::ConnectionAdapters::Table:0x9286a28>
I have run the following line
rails g devise:install
Any reason devise won't recognize it, do i need to do something to say customer is a devise??
Thanks in advance
It looks like that documentation is outdated.
Try using devise generator, it will create same migration, with correct parameters, it's ok if its an existing model:
rails g devise customer
it should create AddDeviseToCustomers migration
with something similar to this:
class AddDeviseToCustomers < ActiveRecord::Migration
def self.up
change_table(:customers) 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
# Uncomment below if timestamps were not included in your original model.
# t.timestamps
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
note that there is no more t.confirmable