Devise install from existing model/database - ruby-on-rails

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

Related

How to fix the Internal 500 Error in a rails application

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.

Rake db:migrate duplicate with Devise

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

Devise - cant add confirmation functionality

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

Rails 4 SQLite3::SQLException error

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.

rails generate devise User error when migrating

I'm a bit new in Rails world and I try to add a new field in devise schema.
I found this :
rails generate model NAME [field[:type][:index] field[:type]
and tried to apply the command :
rails generate devise User linkedin:string
The process seemed correct :
invoke active_record
create db/migrate/20130902085306_add_devise_to_users.rb
insert app/models/user.rb
route devise_for :users
But when I launch a db:migrate it occures an error :
PG::Error: ERROR: column "email" of relation "users" already exists
What did I do wrong ? why does it say (and is it related) email is wrong while it was ok before ?
Thanks a lot !
Here is the migration file result :
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
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.string :linkedin
# Uncomment below if timestamps were not included in your original model.
# 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
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 your users table already have email field? It seems there is, you have to remove creating an email field again by removing it from migration and make sure it is not referenced twice in user.rb model
db/migrate/20130902085306_add_devise_to_users.rb
Ok!
I've found what was wrong : I created a new table instead of updating existing one.
So the good task was :
rails g migration add_columnLinkedin_to_users
Then adding in the new created migration file :
change_table :users do |t|
t.string :linkedin
end
And db:migrate was a success !
Thanks for your helps !

Resources