Rails and Devise giving Error for Signup Page - ruby-on-rails

I've googled and SOed for the answer to this, so even though this question is similar to others posed already, please know I have tried all of the answers posted here already.
I've been following a tutorial to set up a Rails site with users etc. I'm at the stage where I tried to use Devise to generate a user db.
I get this error when I try to access the signup page:
ActiveRecord::StatementInvalid in Devise::RegistrationsController#new
The advice I have found is to use rake db:migrate in order to fix the db.
This gives me the following error:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "installs" ADD "email" varchar(255) DEFAULT '' NOT NULL/ruby/testapp/omrails/db/migrate/20130510151217_add_devise_to_installs.rb:5:in `block in up'
/ruby/testapp/omrails/db/migrate/20130510151217_add_devise_to_installs.rb:3:in `up'
/Users/BWS/.rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `eval'
/Users/BWS/.rvm/gems/ruby-1.9.3-p392/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => db:migrate
The interwebs then leads me to believe that deleting my development.sqlite3 and rerunning rake db:migrate will solve my problem, however this leads to:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "installs" ADD "email" varchar(255) DEFAULT '' NOT NULL/ruby/testapp/omrails/db/migrate/20130510151217_add_devise_to_installs.rb:5:in `block in up'
again.
[Possibly Related]
I also receive the following message when I do just about anything with rails:
/Users/BWS/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/yaml.rb:56:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
But all of the suggested advice online has yet to fix the issue.
Sorry for the long post, trying to be very thorough, any advice would be appreciated.
Update:
So I can't get it to generate a new schema (I trashed the DB folder several times to try different things) but here is one of the deleted ones:
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 0) do
end

It looks like you have two migrations that both adds an email field to installs. You have to look through all you migration files and see if this is true. There are three ways to add a email field to a table, so look for more then one of these:
#1
create_table "installs" do |t|
t.string :email
#2
change_table "installs" do |t|
t.string :email
#3
add_column :installs, :email, :string

Some versions of Devise create migrations without the .rb extension. When I had the same error as you I navigated back to the 'migrate' folder and sure enough the generated migration lacked the extension. Adding .rb and then running $ rake db:migrate fixed this issue for me.

Related

Why is rails 5 adding nextval method in schema file?

After upgrading to Rails 5 my schema file keeps getting altered when running db:migrate. Rails is changing:
create_table "flightlessons", force: :cascade do |t|
to:
create_table "flightlessons", id: :integer, default: -> { "nextval('lessons_id_seq'::regclass)" }, force: :cascade do |t|
It only occurs on this one model. Why is rails implementing nextval on this particular model? And, why is it getting the model name wrong (lessons_id_seq should be flightlessons_id_seq). Manually changing it to flightlessons_id_seq, however, results in the same no relation error.
PG::UndefinedTable: ERROR: relation "lessons_id_seq" does not exist
To proceed, I simply alter the schema.rb file back to what that line 'should' be. Then, I can migrate or test:prepare or whatever until the next time rails alters it back to using the nextval method.
Thank you for any insight into this.
This is a bit long of an answer, so I've broken it into sections. Buckle up!
My theory
My guess is that your development database does contain the lessons_id_seq sequence, and that its definition of flightlessons.id is set to depend on it (i.e., exactly what Rails is putting into your schema file).
How and why? You likely renamed the lessons table to flightlessons at some point in the past, but that rename didn't change the sequence that the table depended on -- and since schema.rb does not record sequences, the lessons_id_seq sequence does not get copied to your test database, and thus you get this error.
To verify my theory, run rails db and try the following commands:
\d lessons_id_seq
This should return the definition of that sequence. Then, try:
\d flightlessons
And look at the definition of the id column. I expect it to include DEFAULT nextval('lessons_id_seq').
Fixes
The easiest way to fix this is to switch to using structure.sql instead of schema.rb (see the docs). This will carry over the exact state of your database and avoid any interference or interpretation by Rails, which is what's causing your current issue. I always recommend structure.sql for production systems.
However, you can also go into your development database and change the sequence name:
ALTER SEQUENCE lessons_id_seq RENAME TO flightlessons_id_seq;
ALTER TABLE flightlessons ALTER COLUMN id SET DEFAULT nextval('flightlessons_id_seq');
This would be a terrible idea on a production system, but if your issue is just local, it should rectify your current database state with your schema.rb and thus address your current problem. You may wish to encode that into a migration, if you want rails db:drop db:create db:migrate to work on a fresh app.
Why now?
The behavior where Rails is dumping out the default value for your table's primary key may very well be new in Rails 5. Previously, Rails may have just trusted that your ID column had a sane default, and ignored whatever value it actually saw. But I haven't done the research to see if that's true or not.
The simplest fix is to just to rename the sequence in production to match the current table name. E.g. in a production Rails console:
ActiveRecord::Base.connection.execute("ALTER SEQUENCE lessons_id_seq RENAME TO flightlessons_id_seq;")
Turns out it's fine to just rename it, if you haven't done anything fancy with the sequence (like implementing your own Postgres function that references it by name).
Apparently the table points to the sequence by ID, not by name, so the rename is instant and with no ill effects that we could see. More details here: https://dba.stackexchange.com/questions/265569/how-can-i-safely-rename-a-sequence-in-postgresql-ideally-without-downtime
We tried it on staging first, and verified that the ID sequence kept on ticking after making the change in staging and production. Everything just worked.
(Also see Robert Nubel's fantastic answer for more details on what's going on.)

What is the purpose of sqlite_sp_functions in Rails schema.rb?

Like some others, I am having trouble with an error
"ActiveRecord::StatementInvalid: SQLite3::SQLException: object name
reserved for internal use: sqlite_sp_functions: CREATE TABLE
"sqlite_sp_functions" ("name" text, "text" text)"
when running rake test on a Rails project.
The offending lines in schema.rb are:
create_table "sqlite_sp_functions", id: false, force: true do |t|
t.text "name"
t.text "text"
end
The suggestions on the previous query about this involved editing schema.rb or deleting that file & regenerating it, but schema.rb (and the offending code) are regenerated on each migration (plus, I don't want to delete Rails-generated code without knowing the implications), so that's not really a satisfactory solution.
So what is the sqlite_sp_functions table for, and how can I get Rails to generate a schema.rb file that doesn't break rake test for the project?
as per https://stackoverflow.com/a/25077833/601782:
Add the following config line to config/application.rb or in config/environments/development.rb:
ActiveRecord::SchemaDumper.ignore_tables = /^sqlite_*/
This will ignore all tables starting with "sqlite_" in your database during the schema dump.
Try removing the offending lines from your schema.rb and then issue:
RAILS_ENV=test rake db:reset
which will completely nuke your testing database but you shouldn't care anyway. You are not supposed to run migrations for test environments. Migrations are meant to be small (reversible) steps for environments that hold data (such as production and sometimes staging/dev).
The preferred way to handle your testing DB is to use db:schema:load as part of your testing routine which will of course delete all your DB data.
Again: Please do not try this in development mode (if you have data that you set up manually) and definitely not in production.
Other than that, you could probably delete the whole sqlite_sp_functions table from your SQLite testing DB and get rid of the issue altogether. I don't think that this has anything to do with Rails (nor is Rails generating that). I believe that SQLite created this table and your schema just picks it up (as it should). Apparently the table is used to hold stored procedures of some kind.

Removing timestamp fields from the schema

I had used default generator to create some tables and they all had that t.timestamp in their definition so the schema that was created also has created_at and updated_at fields.
Now I am told that I don't need those two fields in my schema so I went to the original create_table* files and took out t.timestamp line from them and ran the db:migrate and schema:load commands
But still when I go to my schema.rb file I can see they are still there.
Is there anything wrong I am doing here?
Run
rails g migration remove_timestamps_from_table created_at updated_at
with table being your model's name. Since this is following the pattern remove x from y, rails is smart enough to generate the appropriate migration for you.
Then run
rake db:migrate
to update your development database and
rake db:test:prepare
to prepare the test database, and you're all set!
Read more on migrations here. If you are still having trouble, consider restarting your rails server or database server.

Rails SQLite3 duplicate column - Treehouse Tutorial

I've just started a Treehouse tutorial working on a Simple Ruby App. To give context, I previously had to delete and start over on this project, which I deleted the main app folder and started over.
Following the tutorial we've created a User database which includes all Devise included tables (:email, :name, etc). The error that I'm getting states that I have a duplicated column name. After reviewing and tinkering I tried to comment out the problem column to see if things will move forward in my migration but it just gives the same error for the next line.
A few times I've tried to drop the database, re-create and re-migrate but I'm getting the same issue.
Ideally I'd like to just remove the databases and recreate them, but that doesn't seem like something I can do.
Here is the error:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "email" varchar(255) DEFAULT '' NOT NULL
/Users/pbj/Desktop/code/rails/treebook/db/migrate/20121130035155_add_devise_to_users.rb:5:in `block in up'
/Users/pbj/Desktop/code/rails/treebook/db/migrate/20121130035155_add_devise_to_users.rb:3:in `up'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
When I generated the User set from Devise it also gave me the create_status.rb, devise_create_user.rb and add_devise_to_users.rb (which is the problematic file). The thought of removing Devise and starting over crossed my mind, but I've already done that which has brought me to this new error.
Apologize if this is somewhat rudimentary for all the experience programmers, but as mentioned above, I'm learning but just got off of the original path of this tutorial.
Any and all help is appreciated.
I think despite of your db/migrate/0000-00000_create_user.rb you have added another add_email_to_users migration to your model. So check your create_user.rb in db/migration folder and see if email column is already there, then check for other migration file such as add_email_to_users.rb in db/migrate folder, if you found such an extra add_email migration then delete it.
At the end rename/delete your development.sqlite3 file and try to rake db:migrate from scratch.
this might help you solve the problem.
I'm taking the same course and I think the error lies that Ruby 4 just came out and it has a duplicated line on the migrate directory, I deleted and then ran rake db:migrate. It worked perfectly.
Your error message said this:
duplicate column name: email: ALTER TABLE "users" ADD "email" varchar(255) DEFAULT '' NOT NULL
Your migration file (some random number then...)_add_devise_to_users.rb is adding these lines which you should now comment out
# t.string :email, null: false, default: ""
# add_index :users, :email, unique: true
This will allow you to now migrate with this command
rake db:migrate
If you are still struggling and don't mind destroying and recreating the database you can do this to start fresh
rake db:drop db:create db:migrate
Hope this helps!

Error during migration while setting up Devise

I'm relatively new to Rails and I'm running into an issue while trying to set up Devise. I believe the issue stems from the fact that I already generated a user scaffold before trying to install Devise, yet I don't know how to solve this problem. When I proceed through the Devise setup, I get to the step where I have to enter the following code:
rails generate devise User
That works, and I get this back from terminal:
invoke active_record
create db/migrate/20120609032448_add_devise_to_users.rb
insert app/models/user.rb
route devise_for :users
The next step is to migrate the database, which I attempt but get the following error:
== AddDeviseToUsers: migrating ===============================================
-- change_table(:users)
rake aborted!
An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "email" varchar(255) DEFAULT '' NOT NULL
Tasks: TOP => db:migrate
I've tried destroying the original User scaffold along with the original User migration but I keep getting stuck at this error. Help would be much appreciated!
Your new migration probably has an email column defined in it. Comment that line regarding adding an email column out and run it again. It's likely you've already got an email column in your model.
Try going to this file
db/migrate/20120609032448_add_devise_to_users.rb
and in the code where it says
change_table(:users)...
alter this to
create_table(:users)...

Resources