Cannot figure out what's going on. The test is failing on the uid uniquness matcher, but for a non-null violation on the first_name column, even though the first-name column matcher is passing. uid is an optional db column for if a user signs-up via omniauth like facebook or linkedin login. I'm creating valid objects prior to running the tests using FactoryGirl and have tried explicitly setting the column values before running the tests. I've dropped all the tables, re-migrated and still have issues. I've changed syntaxes, used expect vs. should and am out of ideas of what is causing this test to fail. Below is reference of the other places I've tried solutions from. Rails version 4.0.5, rspec with shoulda in the test group.
Failure/Error: it { should validate_uniqueness_of(:uid).allow_nil }
ActiveRecord::StatementInvalid:
PG::NotNullViolation: ERROR: null value in column "first_name" violates not-null constraint
DETAIL: Failing row contains (110, , , null, null, null, 0, null, null, null, null, 8b1502d6d14a267788d9c06c0412428a4be235f8c4b5b01c8a0d14a1790ff0d3, null, 2014-10-17 04:40:19.569064, null, 2014-10-17 04:40:19.373726, 2014-10-17 04:40:19.373726, null, null, null, null, a).
: INSERT INTO "users" ("confirmation_sent_at", "confirmation_token", "created_at", "uid", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
#spec/models/user_spec.rb
require "spec_helper"
describe User do
let(:user) { create :user}
it { should have_db_column(:first_name).of_type(:string).with_options(null: false) }
it { should have_db_column(:last_name).of_type(:string).with_options(null: false) }
it { should have_db_column(:phone_number).of_type(:string) }
it { should have_one(:professional_profile).dependent(:destroy) }
it { should respond_to(:first_name) }
it { should respond_to(:last_name) }
it { should respond_to(:phone_number) }
describe 'validations' do
subject { build(:user, first_name: "Hello") }
it { should validate_presence_of(:first_name) }
it { should validate_presence_of(:last_name) }
it { should validate_uniqueness_of(:uid).allow_nil }
end
...
#models/user.rb
class User < ActiveRecord::Base
rolify
...
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable,
omniauth_providers: [:linkedin]
validates :first_name, presence: true
validates :last_name, presence: true
validates :uid, uniqueness: true, allow_nil: true
...
What's your :user factory look like?
hey @mcmire, here is our user factory:
FactoryGirl.define do
factory :user do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
email { Faker::Internet.email }
password { Faker::Lorem.characters(20) }
sign_in_count 0
after(:build) {|user| user.confirm! }
factory :unconfirmed_user do
after(:build) do |user|
user.update(confirmed_at: nil)
user.update(confirmation_token: Faker::Lorem.characters(20))
end
end
factory :admin do
after(:build) {|user| user.add_role :admin }
end
factory :profile_manger do
after(:build) {|user| user.add_role :profile_manager }
end
factory :profile_viewer do
after(:build) {|user| user.add_role :profile_viewer }
end
end
end
@stephen-puiszis Okay and I assume you're using the latest version? I notice you're building the user in your validation tests. Prior to 2.7.0 you had to create the user instead, but a fix went in that made it you wouldn't get the sort of error you got.
If you are using 2.7.0 can you provide a backtrace?
@mcmire We were using 2.5. However, I just updated to 2.7 and am still receiving the same errors. The valiadation specs that I posted was the most recent solution I tried. This is how I was running the user_spec prior to running into this issue. Full backtrace further down.
#user_spec.rb
require "spec_helper"
describe User do
let(:user) { create :user }
it { should have_db_column(:first_name).of_type(:string).with_options(null: false) }
it { should have_db_column(:last_name).of_type(:string).with_options(null: false) }
it { should have_db_column(:phone_number).of_type(:string) }
it { should have_one(:professional_profile).dependent(:destroy) }
it { should respond_to(:first_name) }
it { should respond_to(:last_name) }
it { should respond_to(:phone_number) }
it { should validate_presence_of(:first_name) }
it { should validate_presence_of(:last_name) }
it { should validate_uniqueness_of(:uid).allow_nil }
...
Backtrace below:
User
should require case sensitive unique value for uid (FAILED - 1)
Failures:
1) User should require case sensitive unique value for uid
Failure/Error: it { should validate_uniqueness_of(:uid).allow_nil }
ActiveRecord::StatementInvalid:
PG::NotNullViolation: ERROR: null value in column "first_name" violates not-null constraint
DETAIL: Failing row contains (635, , , null, null, null, 0, null, null, null, null, 038ed99375ea0ec9dda6375583af089a851c4319412b801a081a032092a88f82, null, 2014-10-17 17:49:35.46899, null, 2014-10-17 17:49:35.263298, 2014-10-17 17:49:35.263298, null, null, null, null, a).
: INSERT INTO "users" ("confirmation_sent_at", "confirmation_token", "created_at", "uid", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/postgresql_adapter.rb:803:in `get_last_result'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/postgresql_adapter.rb:803:in `exec_cache'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:139:in `block in exec_query'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:442:in `block in log'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activesupport-4.0.5/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:437:in `log'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:137:in `exec_query'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:184:in `exec_insert'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:107:in `insert'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/relation.rb:76:in `insert'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/persistence.rb:510:in `create_record'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/attribute_methods/dirty.rb:78:in `create_record'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/callbacks.rb:306:in `block in create_record'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activesupport-4.0.5/lib/active_support/callbacks.rb:383:in `_run__3117067022564426931__create__callbacks'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activesupport-4.0.5/lib/active_support/callbacks.rb:80:in `run_callbacks'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/callbacks.rb:306:in `create_record'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/timestamp.rb:57:in `create_record'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/persistence.rb:478:in `create_or_update'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/callbacks.rb:302:in `block in create_or_update'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activesupport-4.0.5/lib/active_support/callbacks.rb:383:in `_run__3117067022564426931__save__callbacks'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activesupport-4.0.5/lib/active_support/callbacks.rb:80:in `run_callbacks'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/callbacks.rb:302:in `create_or_update'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/persistence.rb:103:in `save'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/validations.rb:51:in `save'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/attribute_methods/dirty.rb:32:in `save'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:270:in `block (2 levels) in save'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:330:in `block in with_transaction_returning_status'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:221:in `within_new_transaction'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:209:in `transaction'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:327:in `with_transaction_returning_status'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:270:in `block in save'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:285:in `rollback_active_record_state!'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/activerecord-4.0.5/lib/active_record/transactions.rb:269:in `save'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:264:in `block in create_record_in_database'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:261:in `tap'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:261:in `create_record_in_database'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:241:in `first_instance'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:237:in `existing_record'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:366:in `existing_value'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:297:in `validate_everything_except_duplicate_nils?'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/shoulda-matchers-2.7.0/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb:220:in `matches?'
# /Users/stephenpuiszis/.rvm/gems/ruby-2.1.1@global/gems/rspec-expectations-2.14.4/lib/rspec/expectations/handler.rb:24:in `handle_matcher'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/memoized_helpers.rb:68:in `should'
# ./spec/models/user_spec.rb:18:in `block (2 levels) in <top (required)>'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:114:in `instance_eval'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:114:in `block in run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:179:in `call'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:179:in `run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_exec'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_eval_with_args'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:247:in `instance_eval_with_args'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:106:in `block (2 levels) in run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:108:in `call'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:108:in `run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:446:in `run_hook'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:340:in `run_around_each_hooks'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:256:in `with_around_each_hooks'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:111:in `run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:390:in `block in run_examples'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:386:in `map'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:386:in `run_examples'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:371:in `run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:28:in `map'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:28:in `block in run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/reporter.rb:58:in `report'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:25:in `run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/runner.rb:80:in `run'
# /Users/stephenpuiszis/.rvm/rubies/ruby-2.1.1/lib/ruby/gems/2.1.0/gems/rspec-core-2.14.7/lib/rspec/core/runner.rb:17:in `block in autorun'
Finished in 0.23331 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:18 # User should require case sensitive unique value for uid
Randomized with seed 59157
@stephen-puiszis Okay and only that test fails? No other test (well, at least validation test) fails?
Right, no other specs (in the entire app) are failing.
Failures:
1) User should require case sensitive unique value for uid
Failure/Error: it { should validate_uniqueness_of(:uid).allow_nil }
ActiveRecord::StatementInvalid:
PG::NotNullViolation: ERROR: null value in column "first_name" violates not-null constraint
DETAIL: Failing row contains (1115, , , null, null, null, 0, null, null, null, null, 24608f9ae84eb83ee4315ebaa6147591ff4ff35537d8eb6b07cc71cdf9fbad22, null, 2014-10-17 18:44:54.367565, null, 2014-10-17 18:44:54.366393, 2014-10-17 18:44:54.366393, null, null, null, null, a).
: INSERT INTO "users" ("confirmation_sent_at", "confirmation_token", "created_at", "uid", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
# ./spec/models/user_spec.rb:18:in `block (2 levels) in <top (required)>'
Finished in 38.14 seconds
566 examples, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:18 # User should require case sensitive unique value for uid
@stephen-puiszis I'm stumped on this one too I'm afraid. Based on v2.7.0, I made a test similar to the following and it passed:
class User < ActiveRecord::Base
validates :first_name, :last_name, presence: true
validates :uid, uniqueness: true, allow_nil: true
end
describe User do
subject do
User.new(
first_name: 'first name',
last_name: 'last name'
)
end
it { should validate_presence_of(:first_name) }
it { should validate_presence_of(:last_name) }
it { should validate_uniqueness_of(:uid).allow_nil }
end
Can you try commenting out some of the things from the model? Or even some tests? Or even some of the after :build's in the factories file?
@mcmire I'm still stumped and haven't been able to figure out why. However, one of the developers on our team developed this workaround:
it { should allow_value(nil).for(:uid) }
describe "unique uid" do
before { user.update_attribute :uid, 12 }
it { should validate_uniqueness_of(:uid) }
end
Since this seems to be an unexplainable edge case, and a workaround exists, I'm going to go ahead and close this issue. Feel free to comment if you find a solution, though.
This happens to me as well when I have a non-null constraint on my model.
# db/migrate/create_channel_articles.rb
class CreateChannelArticles < ActiveRecord::Migration
def change
create_table :channel_articles do |t|
t.integer :article_id, null: false, index: true
t.integer :channel_id, null: false, index: true
t.index [:article_id, :channel_id], unique: true
t.timestamps null: false
end
end
end
# app/model/channel_article.rb
class ChannelArticle < ActiveRecord::Base
belongs_to :article
belongs_to :channel
validates :article, :channel, presence: true
validates :article_id, uniqueness: { scope: :channel_id }
end
# specs/models/channel_article_spec.rb
require 'rails_helper'
RSpec.describe ChannelArticle, type: :model do
it { should belong_to(:article) }
it { should belong_to(:channel) }
it { should validate_presence_of(:article) }
it { should validate_presence_of(:channel) }
it { should validate_uniqueness_of(:article_id).scoped_to(:channel_id) }
end
I get the following:
1) ChannelArticle should require case sensitive unique value for article_id scoped to channel_id
Failure/Error: it { should validate_uniqueness_of(:article_id).scoped_to(:channel_id) }
ActiveRecord::StatementInvalid:
PG::NotNullViolation: ERROR: null value in column "channel_id" violates not-null constraint
DETAIL: Failing row contains (2, 0, null, 2015-03-20 04:19:03.246573, 2015-03-20 04:19:03.246573).
: INSERT INTO "channel_articles" ("article_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:602:in `exec_prepared'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:602:in `block in exec_cache'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract_adapter.rb:466:in `block in log'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract_adapter.rb:460:in `log'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:601:in `exec_cache'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql_adapter.rb:585:in `execute_and_clear'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `exec_query'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:192:in `exec_insert'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:108:in `insert'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/relation.rb:64:in `insert'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/persistence.rb:521:in `_create_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/counter_cache.rb:139:in `_create_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/attribute_methods/dirty.rb:127:in `_create_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/callbacks.rb:306:in `block in _create_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:88:in `call'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:88:in `_run_callbacks'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:734:in `_run_create_callbacks'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/callbacks.rb:306:in `_create_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/timestamp.rb:57:in `_create_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/persistence.rb:501:in `create_or_update'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/callbacks.rb:302:in `block in create_or_update'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:117:in `call'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:117:in `call'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `block in halting'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `call'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:169:in `block in halting'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:92:in `call'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:92:in `_run_callbacks'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:734:in `_run_save_callbacks'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/callbacks.rb:302:in `create_or_update'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/persistence.rb:120:in `save'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/validations.rb:37:in `save'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/attribute_methods/dirty.rb:21:in `save'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:286:in `block (2 levels) in save'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:347:in `block in with_transaction_returning_status'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/transaction.rb:188:in `within_new_transaction'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:220:in `transaction'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:344:in `with_transaction_returning_status'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:286:in `block in save'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:301:in `rollback_active_record_state!'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.0/lib/active_record/transactions.rb:285:in `save'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:306:in `block in create_record_in_database'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:303:in `tap'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:303:in `create_record_in_database'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:279:in `first_instance'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:275:in `existing_record'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:335:in `block in set_scoped_attributes'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:332:in `each'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:332:in `all?'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:332:in `set_scoped_attributes'
# /Users/rafaelgonzalez/.rvm/gems/ruby-2.2.1/gems/shoulda-matchers-2.8.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:245:in `matches?'
# ./spec/models/channel_article_spec.rb:11:in `block (2 levels) in <top (required)>'
It's like it is creating the model without setting the attributes that have null constraints on them. If I remove the non-null constraint from my migration and regenerate the DB, the tests pass.
EDIT: Updated with the proper error message.
Also note that doing this instead:
# app/model/channel_article.rb
validates :article, uniqueness: { scope: :channel }
# specs/models/channel_article_spec.rb
it { should validate_uniqueness_of(:article).scoped_to(:channel) }
Leads me to this other problem: #535
Most likely related to #194 as well.
@rafaelgonzalez Yeah, your issue is related to #194. But this is different -- here, none of the columns in the uniqueness validation involve first_name, so there should be no reason that the null constraint should be getting violated.
Most helpful comment
This happens to me as well when I have a non-null constraint on my model.
I get the following:
It's like it is creating the model without setting the attributes that have null constraints on them. If I remove the non-null constraint from my migration and regenerate the DB, the tests pass.
EDIT: Updated with the proper error message.