After migrating a model named 'Archive', all tests fail with an ActiveRecord / error message along the lines of:
ActiveRecord::NotNullViolation: SQLite3::ConstraintException: NOT NULL constraint failed: archives.created_at: INSERT INTO "archives" ("some_thing") VALUES ('MyString')
This was isolated in a new Rails app on a new VM running a fresh install of Ubuntu 18.04.2 with Ruby 2.6.1 and Rails 5.2.3, following The Odin Project's installation instructions. The problem only arises during tests for models named 'Archive', and removing the model's attributes just changes the error to:
ActiveRecord::StatementInvalid: SQLite3::SQLException: incomplete input: INSERT INTO "archives"
My work flow is as follows:
rails new sample_app
cd sample_app
(change sqlite3 in Gemfile to use version '~> 1.3.6' to fix bug at time of this writing)
bundle install
rails g model Archive
Generates this migration:
class CreateArchives < ActiveRecord::Migration[5.2]
def change
create_table :archives do |t|
t.timestamps
end
end
end
rails db:migrate
Creates this schema:
ActiveRecord::Schema.define(version: 2019_04_03_003144) do
create_table "archives", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
rails db:test
Runs this test: (uncommented)
require 'test_helper'
class ArchiveTest < ActiveSupport::TestCase
test "the truth" do
assert true
end
end
After running the test, which would normally be a given pass, Rails returns the first ActiveRecord error message listed above.
I feel like I am missing something here that prevents me from using the word 'Archive' for a model.
Archive is not a reserved word. The link you have provided is not updated in last 5 years.
The reason behind this is:
You are creating a record of Archive without providing created_at and updated_at which are mandatory fields as per your schema.
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
Solution:
Either change your migrations to allow null to be inserted in created_at and updated_at OR go to you test/fixtures/archive.yml and provide created_at and updated_at there.
like:
one:
....some fields....
created_at: 2018-08-30 14:41:23
updated_at: 2018-08-30 14:41:23
UPDATE
Now second issue is because you don't have any field other than timestamp. Drop this table and create new model for Archive with at least 1 field. Currently Rails is generating query INSERT INTO "Archives"; and SQL expects data after this query, that's why it returns error to you.
Related
First off, I am using ar_firebird_adapter which is a nifty adapter that allows Rails and FB to integrate fairly seamlessly (the only adapter that is compatible with Rails 6). The problem that I am having is once I am connected to my Firebird DB and I run rake db:schema:dump, some of the tables come in like so:
# Could not dump table "country" because of following StandardError
# Unknown type 'VARCHAR' for column 'currency'
# Could not dump table "customer" because of following StandardError
# Unknown type 'VARCHAR' for column 'customer'
# Could not dump table "department" because of following StandardError
# Unknown type 'VARCHAR' for column 'department'
# Could not dump table "employee" because of following StandardError
# Unknown type 'VARCHAR' for column 'phone_ext'
create_table "employee_project", primary_key: ["proj_id", "emp_no"], force: :cascade do |t|
t.boolean "emp_no", null: false
t.boolean "proj_id", null: false
t.index ["emp_no", "proj_id"], name: "rdb$primary14", unique: true
t.index ["emp_no"], name: "rdb$foreign15"
t.index ["proj_id"], name: "rdb$foreign16"
end
# Could not dump table "job" because of following StandardError
# Unknown type 'VARCHAR' for column 'job_title'
# Could not dump table "proj_dept_budget" because of following StandardError
# Unknown type 'INTEGER' for column 'fiscal_year'
# Could not dump table "project" because of following StandardError
# Unknown type 'VARCHAR' for column 'proj_name'
As you can see, any DB that is clear and void of "unknown" types comes across fine but the above types get listed as a StandardError (including TIMESTAMP)
Now, I read that I need to use rake db:structure:load after putting this into my application.rb:
config.active_record.schema_format = :sql
Problem is, when I use rake db:structure:load, this is the error I get:
rake aborted!
ActiveRecord::Tasks::DatabaseNotSupported: Rake tasks not supported by 'ar_firebird' adapter
Tasks: TOP => db:structure:dump
Does this mean the adapter does not utilize that rake command and if so, how do I fix it? This is a huge hurdle I need to get over! I will be elated if someone can help me.
So.. the answer was fairly simple; try another adapter made by the same group of guys!
I ended up using firebird_adapter and db:schema:dump worked like a charm.
I did have to account for a few unknown data types within the gem, but other than that, it was all good.
Thanks for those that looked/commented.
Rails 6
environment: local development on Mac OS
DB server: MySQL
I deleted all the tables from the DB, and the only tables left in the DB are:
schema_migrations
ar_internal_metadata
I made sure that schema_migrations has no data in it and looked into ar_internal_metadata, and that table has a single row in it, with the following values:
key: environment, value: development
I have several migrations, the most recent one, is devise_create_users.rb.
I am trying to run:
rake db:migrate
But I am getting the error message:
=> rake db:migrate
== 20200317184535 DeviseCreateUsers: migrating ================================
-- create_table(:users)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'users' already exists
/Users/dev/rails/myapp/db/migrate/20200317184535_devise_create_users.rb:5:in `change'
Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'users' already exists
/Users/dev/rails/myapp/db/migrate/20200317184535_devise_create_users.rb:5:in `change'
Caused by:
Mysql2::Error: Table 'users' already exists
/Users/dev/rails/myapp/db/migrate/20200317184535_devise_create_users.rb:5:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Process finished with exit code 1
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.string :reset_password_token
t.datetime :reset_password_sent_at
t.datetime :remember_created_at
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.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
end
When I check the DB after this, I still don't see a users table, and the schema_migrations table is still empty. In addition, the DeviseCreateUsers migration is the most recent on, so why is it running first.
Any ideas?
Edit:
Based on a comment to the question, I looked at my database.yml file:
default: &default
host: localhost
database: <%= ENV['RAILS_DB_NAME'] %>
username: <%= ENV['RAILS_DB_USER'] %>
password: <%= ENV['RAILS_DB_PWD'] %>
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
socket: /tmp/mysql.sock
development:
<<: *default
I made that change last night, and I forgot that my local ENV settings, were for a different project, so Rails was picking up the settings for that project, and was indeed correct, in that the users table is already there. The fix was for me to create project specific ENV settings, for my local development environment
When things like this happen it is needed to check the database.yml. As in most cases it happens because of some faulty configuration.
Good thing that just mentioning the database.yml in the comment section of the question helped to find the problem.
Using rails console to make sure there is not any users table, try create a new instance of User User.new. If the object was instanciated, your User table is hidden in somewhere. It is not a problem, see all atributtes previously generated and just migrate new ones. I can see in your devise_create_user migration that you can just replace it with something like addColumnstoUser.rb. This will just add the apropriated columns necessary to let Devise runing well.
Choosing this way, inside your migration:
add_column :table_name, :fieldname, :type, in your case, using just one column as an example, it must be:
def change
add_column :users, :reset_password_token, :string
end.
If you are using version controll, such as git, the migration might not know where you can rollback or go ahead. All the migration and rollbacks must stay on the same branch.
For example:
1) Adding a new branch to handle user migration: git checkout -b generate-user-model, generating user model rails generate model User name:string email:string
and running the migration rails db:migrate will create the users table and will update scheema.rb (check scheema file). Adding it to version controll git add . and `git commit -m "Migrating user model"
2) Moving to a new branch git checkout -b comments-controller, generating a new controller rails generate model Comment. And then migrating it rails db:migrate.
This second migration only teachs scheema.rb how to go ahead and how to rollback on this specifc migration. This last git branch doesn't know nothing about how to rollback the User model, unless you merge a branch inside another git merge generate-user-model.
After many migrations has been used, it's usefull keep using migrations to add or delete tables.
Hence, If I had a table called users and I wanted to set it to handle Devise, I just need to generate a new migration with the columns I'd needed.
Use https://sqlitebrowser.org/ to help you cheking your database tables and columns.
I'm running two projects as a different repository with git. One is admit another one is Web in rails, both are connected with each other, Basically same database is used. I only made the migration on admin report and then cloned it into the web. The problem is, I'm deploying it on the server and test cases failed the error says
ActionView::Template::Error: PG::UndefinedColumn: ERROR: column fees.discount does not exist
I just don't understand why it has been happening, in admin I have that field presents.
I think schema.rb may playing role in this case. I'm not so sure about it.
Here is my migration,
class AddDiscountToFeel < ActiveRecord::Migration[5.0]
def change
add_column :fees, :discount, :integer, default: nil, null: true
end
end
And here is my Model fields in development:
2.3.1 :008 > Fee.column_names
=> ["id", "booth_id", "amount", "description", "created_at", "updated_at", "discount"]
And here is my Model fields in test:
C238s-iMac:web c238$ RAILS_ENV=test rails c
Loading test environment (Rails 5.0.0.1)
2.3.1 :001 > Fee.column_names
=> ["id", "booth_id", "amount", "description", "created_at", "updated_at", "discount"]
And here is my error's snap:
Any help will be appreciated.
Yes, I was right
It has been long time in web that I haven’t updated schema from admin that’s why I’ve faced this issue.
Solution: Copied schema.rb from admin into web repo, because both projects use same DB.
May the answer will helpful for someone also.
Can try to run to add discount to the table?
bundle exec rake db:migrate
if using heroku:
heroku run rake db:migrate
I have started a new rails 5 application:
rails new projectOne --api --database=postgresql
created a user model:
rails g model user
with corresponding table migration:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :email, null: false
t.string :password_digest, null: false
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.timestamps
end
end
end
When I run the following minitest test:
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "the truth" do
assert true
end
end
The output is:
Error:
UserTest#test_the_truth:
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "email" violates not-null constraint
DETAIL: Failing row contains (980190962, null, null, null, null, null, 2017-09-10 18:58:52.08302, 2017-09-10 18:58:52.08302).
: INSERT INTO "users" ("created_at", "updated_at", "id") VALUES ('2017-09-10 18:58:52.083020', '2017-09-10 18:58:52.083020', 980190962)
In the console, I can create an empty User object and as expected receive the above error, but I do not understand what is trying to create the object within my test. I'd appreciate an explanation and some advice of how to get this test to pass.
The command bundle exec rails g model SomeModel is invoking a bunch of generators include a test generator. The test generators generate a test template and fixtures:
Fixtures is a fancy word for sample data. Fixtures allow you to
populate your testing database with predefined data before your tests
run. Fixtures are database independent and written in YAML. There is
one file per model.
The minitest trying to load environment and populate your test database with fixtures, which fails in your case. Look's like you have invalid fixtures. In order to resolve your issue check the forlder test/fixtures and fix or delete your fixtures.
Read more about testing in Rails.
I am following Michael Hartl's book and I am getting this error when I run the server:
I am getting ActiveRecord::PendingMigrationError when I run the server, this shows up:
Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development
Please I've been stuck in this error for so long.
When I type $ RAILS_ENV=development rake db:migrate I get this error:
== 20161209073230 AddActivationToUsers: migrating =============================
-- add_column(:users, :activation_digest, :string) rake aborted! StandardError: An error has occurred, this and all later migrations
canceled:
SQLite3::SQLException: duplicate column name: activation_digest: ALTER
TABLE "users" ADD "activation_digest" varchar
(required)>' Tasks: TOP => db:migrate (See full trace by running task
with --trace)
test/mailers/previews/user_mailer_preview.rb
UserMailerPreview < ActionMailer::Preview
# Preview this email at
http://localhost:3000/rails/mailers/user_mailer/account_activation
def account_activation
user = User.first
user.activation_token = User.new_token
UserMailer.account_activation(user) end
# Preview this email at
http://localhost:3000/rails/mailers/user_mailer/password_reset def
password_reset
UserMailer.password_reset end
end
Schema.rb:
# 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 that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161123005710) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.string "activation_digest"
t.index ["email"], name: "index_users_on_email", unique: true end
end
Latest migration is
db/migrate/[timestamp]_add_activation_to_users.rb:
class AddActivationToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :activation_digest, :string
add_column :users, :activated, :boolean, default: falserao
add_column :users, :activated_at, :datetime
end
end
The correct command to apply unapplied migrations is RAILS_ENV=development rake db:migrate
This just means that you have a migration pending. When you create a new migration
railas g migration MigrationName
it means that it changes something in the database schema or the layout of your database. In order to commit that change, you have to run:
bin/rails db:migrate
This will look into your migration file and apply it to your databse. Once the migration is done, you can run server as usual again.
rails server
If you have more question, I recommend reading the migration documentation that Rails published:
http://guides.rubyonrails.org/active_record_migrations.html
SQLite3::SQLException: duplicate column name: activation_digest:
(The following is the SQL command that actually modifies the db):
ALTER TABLE "users" ADD "activation_digest"
The SQL command reads like plain English. Somehow one of your migrations is doing something a previous migration already did, namely adding the activation_digest column to your users table in the db. If you look in the directory db/migrate/, you will see all your migration files. If you open one of them up, you should sort of be able to tell what it is doing. So look at all your migration files and find the two migrations that both add the activation_digest column. If the two migration files are identical, then you need to delete one--but take the following steps before deleting a migration:
https://www.baserails.com/questions/i-messed-up-while-generating-my-migration-how-can-i-undo-it
Also check out the section Rolling Back in the Rails Guide:
http://edgeguides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations
If for some reason you don't have two identical migration files that both add the activation_digest column, e.g one of the migration files does something additionally, then you need to figure out what steps in the tutorial that you did wrong, then rollback to the last migration that you know is correct. Finally, follow the steps in the tutorial again for generating the subsequent migrations.
It seems your users table already have a column named activation_digest. Remove the add_column line where the column is added from the migration file and run the migration again.
I think this migration file should work:
class AddActivationToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :activated, :boolean, default: false
add_column :users, :activated_at, :datetime
end
end
Ok the answer is very simple!Just try migrating your DB to version=0 with command: rake db:migrate VERSION=0
and then run rake db:migrate