rspec model test failing - ruby-on-rails

I am writing an app to help me keep track of my social media advertising budgets. When you enter a new advert it should calculate and update the amount spent on the budget it is drawing from. Here is my model that achieves that.
class Advert < ActiveRecord::Base
belongs_to :budget
before_save :update_budget
after_destroy :update_budget
validates :budget_id, :name, :platform, :ad_type, :amount, :start_date, :end_date, presence: true
validates :amount, numericality: true
validate :check_budget
# Checks to see if there is enough budget remaining to set up advert
def check_budget
if self.amount > self.budget.amount_remaining
errors.add(:amount, " cannot exceed amount remaining in budget.")
end
end
# Updates the amount remaining in the budget on advert save.
def update_budget
budget = Budget.find(self.budget_id)
#adverts = Advert.all
total_spent = self.amount
#adverts.each do |advert|
if advert.budget_id == self.budget_id
total_spent += advert.amount
end
end
budget.amount_spent = total_spent
budget.save
end
end
This all works but I am currently teaching myself to write tests so I thought I would write a test in rspec for it.
require 'rails_helper'
describe Advert do
it "updates budget before save" do
advert = create(:advert)
budget = advert.budget
expect(budget.amount_spent).to eq(advert.amount)
expect(budget.amount_remaining).to eq(budget.amount - budget.amount_spent)
end
end
However, this test if failing but I cannot figure out why. Here is the error code.
1) Advert updates budget before save
Failure/Error: expect(budget.amount_spent).to eq(advert.amount)
expected: 7.0 (#<BigDecimal:7ffa61358b18,'0.7E1',9(18)>)
got: 0.0 (#<BigDecimal:7ffa6026a9a0,'0.0',9(18)>)
(compared using ==)
# ./spec/models/advert_spec.rb:27:in `block (2 levels) in <top (required)>'
And here is the relevant test log.
SQL (0.3ms) INSERT INTO "budgets" ("name", "amount", "client_id", "amount_remaining", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["name", "eos"], ["amount", "432.0"], ["client_id", 102], ["amount_remaining", "432.0"], ["created_at", "2016-03-12 18:08:54.607999"], ["updated_at", "2016-03-12 18:08:54.607999"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
(0.2ms) SAVEPOINT active_record_1
Budget Load (0.4ms) SELECT "budgets".* FROM "budgets" WHERE "budgets"."id" = $1 LIMIT 1 [["id", 49]]
Advert Load (0.5ms) SELECT "adverts".* FROM "adverts"
SQL (0.4ms) UPDATE "budgets" SET "amount_spent" = $1, "amount_remaining" = $2, "updated_at" = $3 WHERE "budgets"."id" = $4 [["amount_spent", "7.0"], ["amount_remaining", "425.0"], ["updated_at", "2016-03-12 18:08:54.616491"], ["id", 49]]
SQL (0.4ms) INSERT INTO "adverts" ("budget_id", "name", "platform", "ad_type", "amount", "start_date", "end_date", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id" [["budget_id", 49], ["name", "ut"], ["platform", "voluptate"], ["ad_type", "facere"], ["amount", "7.0"], ["start_date", "2016-03-01"], ["end_date", "2016-04-12"], ["created_at", "2016-03-12 18:08:54.619698"], ["updated_at", "2016-03-12 18:08:54.619698"]]
(0.2ms) RELEASE SAVEPOINT active_record_1
(0.2ms) ROLLBACK
Interestingly if I comment out the first 'expect' the test passes. It's as though it cannot access advert.amount so set's it as 0.
Anyone have any ideas?

This solved my issue.
describe Advert do
it "updates budget before save" do
advert = build(:advert)
budget = advert.budget
expect(budget.amount_spent).to eq(0)
advert.save
budget.reload
expect(budget.amount_spent).to eq(advert.amount)
expect(budget.amount_remaining).to eq(budget.amount - budget.amount_spent)
end
I think the source of my problem was not reloading my budget which meant that I was trying to access the attribute before it had been updated.

Related

Rails Nested Attributes trying to update a record id

I have a problem with nested_attributes, I have the next entities:
class Experience < ActiveRecord::Base
has_many :roles, inverse_of: :experience
end
class Role < ActiveRecord::Base
belongs_to :experience, inverse_of: :roles
end
I have the next set of parameters:
params = {"end_date"=>"02/01/2012",
"city"=>"Buenos Aires",
"state"=>"",
"country"=>"",
"title"=>nil,
"company"=>"Restorando",
"current"=>nil,
"description"=>nil,
"roles_attributes"=>
[{"id"=>558, "title"=>"System Owner", "start_date"=>"03/01/2000", "end_date"=>"02/01/2001", "description"=>"<p>I did a bunch of stuff</p>", "current"=>false},
{"id"=>561, "title"=>"Test", "description"=>nil, "current"=>nil},
{"id"=>557, "title"=>"Full Stack Developerr", "start_date"=>"01/01/2011", "end_date"=>"02/01/2012", "description"=>"<p>Full Stack Developer description</p>", "current"=>false}],
"resumes_experiences_attributes"=>[{"id"=>384, "resume_id"=>809}, {"id"=>385, "resume_id"=>3199}]}
And I want to update a rails model. So I execute:
#experience = Experience.find(some_id)
#experience.update_attributes(params)
This returns me an error
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate
key value violates unique constraint "roles_pkey"
If I see what Rails is trying to update I see the next sql statement:
UPDATE "roles" SET "start_date" = $1, "end_date" = $2, "current" = $3,
"id" = $4, "description" = $5, "title" = $6, "created_at" = $7,
"updated_at" = $8 WHERE "roles"."id" = $9 [["start_date", nil],
["end_date", nil], ["current", nil], ["id", 561], ["description",
nil], ["title", "Test"], ["created_at", "2017-06-23 10:54:10.194605"],
["updated_at", "2017-06-23 10:54:10.194605"], ["id", 558]]
Which to me is strange because it's trying to update a record id, if you see the statement you will see: "id" = $4 and the where clause WHERE "roles"."id" = $9 which is correct, but its taking two different id values.
Instead if I execute:
#experience = Experience.include(:roles).find(some_id)
#experience.update_attributes(params)
It works perfectly
The initial case also works if I enter a rails console and manually trigger it. I don't know why this is happening, of course there are more complexity in the applications and I just give you the basic data to solve it but any insight would be helpful.

Cannot Login User when Using Selenium with Rails/RSpec

I am running tests that starts by logging in a user using the login form. It successfully opens Firefox, navigates to the login form and fills in the fields, but when it clicks the 'Login' button, it hangs indefinitely. When I quit Firefox the test that was running fails, but I am not getting any additional error message.
Any idea what I am doing wrong? This is driving me crazy and preventing me from testing a big portion of my app, any help would be much appreciated! Thanks!
Here is some additional info:
Rails 4.2.0
Ruby 2.2.4
Capybara 2.6.2
Selenium-Webdriver 2.53.0
Firefox 46.0.1
Using Capybara with RSpec
Capybara.javascript_driver = :selenium
/spec_helper.rb
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
require 'simplecov'
SimpleCov.start 'rails'
require 'capybara/rspec'
require 'aasm/rspec'
RSpec.configure do |config|
config.include Capybara::DSL
def test_sign_in(user)
# helper method to sign in the passed-in user
visit new_user_session_path
within ('#user-login-non-modal') do
within(".user-login") do
fill_in 'Email', with: user.email
fill_in 'Password', with: 'foobar11'
click_button 'Sign in'
end
end
end
def test_partner_sign_in(partner)
# helper method to sign in the passed-in partner
visit new_partner_session_path
within('#partner-login-non-modal') do
within(".partner-login") do
fill_in 'Email', with: partner.email
fill_in 'Password', with: 'foobar11'
click_button 'Sign in'
end
end
end
# configure database cleaner
config.before(:suite) do
DatabaseCleaner.start
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
# if config.files_to_run.one?
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
# config.default_formatter = 'doc'
# end
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
/rails_helper.rb
# This file is copied to spec/ when you run 'rails generate
rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'devise'
require 'controller_macros'
require 'byebug'
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.include Devise::TestHelpers, :type => :controller
config.include Rails.application.routes.url_helpers
config.extend ControllerMacros, :type => :controller
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
end
/test.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Configure static asset server for tests with Cache-Control for performance.
config.serve_static_files = true
config.static_cache_control = 'public, max-age=3600'
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# For Devise
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
.rspec
--color
--require spec_helper
--drb
Edit:
user_pages_spec.rb
describe "show page" do
before do
# #user = FactoryGirl.create(:user)
#user = User.invite!(:email => "test_user#example.com", :skip_invitation => true)
#user.accept_invitation!
#user.password = "foobar11"
#user.first_name = "John"
#user.last_name = "Smith"
#user.save
#car1 = FactoryGirl.create(:car, user: #user)
#car2 = FactoryGirl.create(:car, user: #user)
#tomorrow = Time.now + 24*60*60
#earlier_today = Time.now - 30
#app_in_future1 = FactoryGirl.create(:appointment, car: #car1, garage: #car1.garage, pickuptime: #tomorrow)
#app_in_future2 = FactoryGirl.create(:appointment, car: #car1, garage: #car1.garage, pickuptime: #tomorrow + 24*60*60)
#app_in_past = FactoryGirl.build(:appointment, car: #car1, garage: #car1.garage, pickuptime: #earlier_today)
#app_in_past.save(validate: false)
different_pickup_time = #tomorrow + 60*60
#different_user = FactoryGirl.create(:user)
#car_different_user = FactoryGirl.create(:car, make: "diff_make", user: #different_user)
#app_different_user = FactoryGirl.create(:appointment, car: #car_different_user, garage: #car_different_user.garage, pickuptime: different_pickup_time)
test_sign_in(#user)
end
describe "adding an appointment to a car", js:true do
context "when the appointment is in the future" do
it "should increment the number of the car's appointments" do
expect do
within(".create-appt-row-#{#car1.id}") do
click_button 'Add Appointment'
fill_in 'appointment_pickuptime', with: "12/07/2100 4:57 PM"
click_button 'Book It'
end
end.to change(#car1.appointments, :count).by(1)
end
end
end
Edit 3:
After updating to selenium-webdriver 2.53.4 and re-running the test that requires the user-login, Firefox is hanging indefinitely, and when I quit Firefox manually I get this error message with the failing test:
Failure/Error: visit new_user_session_path
Errno::ECONNREFUSED:
Connection refused - connect(2) for "127.0.0.1" port 7055
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/default.rb:107:in `response_for'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/default.rb:58:in `request'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:627:in `execute'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:134:in `get'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/common/navigation.rb:33:in `to'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/capybara-2.6.2/lib/capybara/selenium/driver.rb:45:in `visit'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/capybara-2.6.2/lib/capybara/session.rb:232:in `visit'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/capybara-2.6.2/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
# ./spec/spec_helper.rb:23:in `test_sign_in'
# ./spec/requests/user_pages_spec.rb:31:in `block (3 levels) in <top (required)>'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/test_framework/rspec.rb:12:in `run_tests'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/run_strategy/forking.rb:13:in `block in run'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/forker.rb:21:in `block in initialize'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/forker.rb:18:in `fork'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/forker.rb:18:in `initialize'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/run_strategy/forking.rb:9:in `new'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/run_strategy/forking.rb:9:in `run'
# /Users/JAckerman/.rvm/gems/ruby-2.2.4/bundler/gems/spork-224df492657e/lib/spork/server.rb:49:in `run'
Edit 4:
test.log after running the test that hangs
[1m[36mActiveRecord::SchemaMigration Load (0.6ms)[0m [1mSELECT "schema_migrations".* FROM "schema_migrations"[0m
[1m[35m (0.2ms)[0m BEGIN
[1m[36m (0.2ms)[0m [1mCOMMIT[0m
[1m[35m (0.1ms)[0m BEGIN
[1m[36m (1.7ms)[0m [1mALTER TABLE "active_admin_comments" DISABLE TRIGGER ALL;ALTER TABLE "authorizations" DISABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" DISABLE TRIGGER ALL;ALTER TABLE "garagepartners" DISABLE TRIGGER ALL;ALTER TABLE "cars" DISABLE TRIGGER ALL;ALTER TABLE "locations" DISABLE TRIGGER ALL;ALTER TABLE "partners" DISABLE TRIGGER ALL;ALTER TABLE "appointments" DISABLE TRIGGER ALL;ALTER TABLE "images" DISABLE TRIGGER ALL;ALTER TABLE "garages" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "companies" DISABLE TRIGGER ALL;ALTER TABLE "damages" DISABLE TRIGGER ALL;ALTER TABLE "admin_users" DISABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" DISABLE TRIGGER ALL[0m
[1m[35m (2.3ms)[0m SELECT schemaname || '.' || tablename
FROM pg_tables
WHERE
tablename !~ '_prt_' AND
tablename <> 'schema_migrations' AND
schemaname = ANY (current_schemas(false))
[1m[36m (2.0ms)[0m [1mselect table_name from information_schema.views where table_schema = 'parkme3_test'[0m
[1m[35m (55.4ms)[0m TRUNCATE TABLE "public"."active_admin_comments", "public"."authorizations", "public"."authorized_drivers", "public"."garagepartners", "public"."cars", "public"."locations", "public"."partners", "public"."appointments", "public"."images", "public"."garages", "public"."users", "public"."companies", "public"."damages", "public"."admin_users", "public"."delayed_jobs" RESTART IDENTITY CASCADE;
[1m[36m (0.9ms)[0m [1mALTER TABLE "active_admin_comments" ENABLE TRIGGER ALL;ALTER TABLE "authorizations" ENABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" ENABLE TRIGGER ALL;ALTER TABLE "garagepartners" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "cars" ENABLE TRIGGER ALL;ALTER TABLE "locations" ENABLE TRIGGER ALL;ALTER TABLE "partners" ENABLE TRIGGER ALL;ALTER TABLE "appointments" ENABLE TRIGGER ALL;ALTER TABLE "images" ENABLE TRIGGER ALL;ALTER TABLE "garages" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL;ALTER TABLE "companies" ENABLE TRIGGER ALL;ALTER TABLE "damages" ENABLE TRIGGER ALL;ALTER TABLE "admin_users" ENABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" ENABLE TRIGGER ALL[0m
[1m[35mUser Load (1.4ms)[0m SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["email", "test_user#example.com"]]
[1m[36mUser Load (0.6ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."invitation_token" = $1 ORDER BY "users"."id" ASC LIMIT 1[0m [["invitation_token", "12f7e3e1ca7f4be3bf7ebc51410444e1b49d703cade994df75ca75a2e49fed3e"]]
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.7ms)[0m [1mINSERT INTO "users" ("receive_email_notification", "receive_text_notification", "email", "encrypted_password", "invitation_token", "invitation_created_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["receive_email_notification", "t"], ["receive_text_notification", "t"], ["email", "test_user#example.com"], ["encrypted_password", "$2a$04$dzJj7097jsrmaWOfVGqrq.F4wcKx4yktACtDVjI7IXbt6u83C7.QO"], ["invitation_token", "12f7e3e1ca7f4be3bf7ebc51410444e1b49d703cade994df75ca75a2e49fed3e"], ["invitation_created_at", "2016-07-15 15:02:23.921974"], ["created_at", "2016-07-15 15:02:23.923749"], ["updated_at", "2016-07-15 15:02:23.923749"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.3ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.5ms)[0m UPDATE "users" SET "invitation_accepted_at" = $1, "invitation_token" = $2, "updated_at" = $3 WHERE "users"."id" = $4 [["invitation_accepted_at", "2016-07-15 15:02:23.929347"], ["invitation_token", nil], ["updated_at", "2016-07-15 15:02:23.930593"], ["id", 1]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.5ms)[0m [1mUPDATE "users" SET "encrypted_password" = $1, "first_name" = $2, "last_name" = $3, "updated_at" = $4 WHERE "users"."id" = $5[0m [["encrypted_password", "$2a$04$c8LSFWcTJXE7np2W838iLui3lHt7yYXSjQvhQoxt91EqkW1xvBr1q"], ["first_name", "John"], ["last_name", "Smith"], ["updated_at", "2016-07-15 15:02:23.938120"], ["id", 1]]
[1m[35m (0.3ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.5ms)[0m INSERT INTO "companies" ("name", "min_time_in_minutes", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "company_1"], ["min_time_in_minutes", 15], ["created_at", "2016-07-15 15:02:23.977122"], ["updated_at", "2016-07-15 15:02:23.977122"]]
[1m[36m (0.3ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.6ms)[0m [1mINSERT INTO "garages" ("name", "time_zone", "min_time_in_minutes", "urgent_minutes", "use_acknowledgement", "use_locations", "use_damage_tracking", "use_numpad_make_appointment_form", "phone_number", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"[0m [["name", "garage_1"], ["time_zone", "Eastern Time (US & Canada)"], ["min_time_in_minutes", 15], ["urgent_minutes", 60], ["use_acknowledgement", "t"], ["use_locations", "t"], ["use_damage_tracking", "t"], ["use_numpad_make_appointment_form", "f"], ["phone_number", "7777777777"], ["company_id", 1], ["created_at", "2016-07-15 15:02:23.982258"], ["updated_at", "2016-07-15 15:02:23.982258"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.7ms)[0m INSERT INTO "cars" ("make", "car_model", "year", "car_number", "garage_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["make", "make_1"], ["car_model", "car_model_1"], ["year", 2014], ["car_number", 1], ["garage_id", 1], ["user_id", 1], ["created_at", "2016-07-15 15:02:23.988597"], ["updated_at", "2016-07-15 15:02:23.988597"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.3ms)[0m [1mINSERT INTO "companies" ("name", "min_time_in_minutes", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"[0m [["name", "company_2"], ["min_time_in_minutes", 15], ["created_at", "2016-07-15 15:02:23.996186"], ["updated_at", "2016-07-15 15:02:23.996186"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "garages" ("name", "time_zone", "min_time_in_minutes", "urgent_minutes", "use_acknowledgement", "use_locations", "use_damage_tracking", "use_numpad_make_appointment_form", "phone_number", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id" [["name", "garage_2"], ["time_zone", "Eastern Time (US & Canada)"], ["min_time_in_minutes", 15], ["urgent_minutes", 60], ["use_acknowledgement", "t"], ["use_locations", "t"], ["use_damage_tracking", "t"], ["use_numpad_make_appointment_form", "f"], ["phone_number", "7777777777"], ["company_id", 2], ["created_at", "2016-07-15 15:02:23.999804"], ["updated_at", "2016-07-15 15:02:23.999804"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.4ms)[0m [1mINSERT INTO "cars" ("make", "car_model", "year", "car_number", "garage_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["make", "make_2"], ["car_model", "car_model_2"], ["year", 2014], ["car_number", 2], ["garage_id", 2], ["user_id", 1], ["created_at", "2016-07-15 15:02:24.003820"], ["updated_at", "2016-07-15 15:02:24.003820"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.6ms)[0m INSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["aasm_state", "scheduled"], ["pickuptime", "2016-07-16 15:02:24.006227"], ["car_id", 1], ["garage_id", 1], ["created_at", "2016-07-15 15:02:24.026603"], ["updated_at", "2016-07-15 15:02:24.026603"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.4ms)[0m [1mINSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"[0m [["aasm_state", "scheduled"], ["pickuptime", "2016-07-17 15:02:24.006227"], ["car_id", 1], ["garage_id", 1], ["created_at", "2016-07-15 15:02:24.033088"], ["updated_at", "2016-07-15 15:02:24.033088"]]
[1m[35m (0.3ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["aasm_state", "scheduled"], ["pickuptime", "2016-07-15 15:01:54.006233"], ["car_id", 1], ["garage_id", 1], ["created_at", "2016-07-15 15:02:24.039517"], ["updated_at", "2016-07-15 15:02:24.039517"]]
[1m[36m (0.3ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mUser Exists (0.5ms)[0m [1mSELECT 1 AS one FROM "users" WHERE "users"."email" = 'person_1#example.com' LIMIT 1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "users" ("receive_email_notification", "receive_text_notification", "email", "encrypted_password", "invitation_accepted_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["receive_email_notification", "t"], ["receive_text_notification", "t"], ["email", "person_1#example.com"], ["encrypted_password", "$2a$04$glYjOuWxkRp06jc/l1X0ceeI5OD.eqWMzsnt/MRhizfX7RuD7ti9m"], ["invitation_accepted_at", "2016-07-15 14:02:24.045381"], ["created_at", "2016-07-15 15:02:24.053170"], ["updated_at", "2016-07-15 15:02:24.053170"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.2ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.3ms)[0m [1mINSERT INTO "companies" ("name", "min_time_in_minutes", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"[0m [["name", "company_3"], ["min_time_in_minutes", 15], ["created_at", "2016-07-15 15:02:24.060156"], ["updated_at", "2016-07-15 15:02:24.060156"]]
[1m[35m (0.3ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.1ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "garages" ("name", "time_zone", "min_time_in_minutes", "urgent_minutes", "use_acknowledgement", "use_locations", "use_damage_tracking", "use_numpad_make_appointment_form", "phone_number", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id" [["name", "garage_3"], ["time_zone", "Eastern Time (US & Canada)"], ["min_time_in_minutes", 15], ["urgent_minutes", 60], ["use_acknowledgement", "t"], ["use_locations", "t"], ["use_damage_tracking", "t"], ["use_numpad_make_appointment_form", "f"], ["phone_number", "7777777777"], ["company_id", 3], ["created_at", "2016-07-15 15:02:24.063107"], ["updated_at", "2016-07-15 15:02:24.063107"]]
[1m[36m (0.3ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m SAVEPOINT active_record_1
[1m[36mSQL (0.3ms)[0m [1mINSERT INTO "cars" ("make", "car_model", "year", "car_number", "garage_id", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"[0m [["make", "diff_make"], ["car_model", "car_model_3"], ["year", 2014], ["car_number", 3], ["garage_id", 3], ["user_id", 2], ["created_at", "2016-07-15 15:02:24.066940"], ["updated_at", "2016-07-15 15:02:24.066940"]]
[1m[35m (0.2ms)[0m RELEASE SAVEPOINT active_record_1
[1m[36m (0.2ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mSQL (0.4ms)[0m INSERT INTO "appointments" ("aasm_state", "pickuptime", "car_id", "garage_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["aasm_state", "scheduled"], ["pickuptime", "2016-07-16 16:02:24.006227"], ["car_id", 3], ["garage_id", 3], ["created_at", "2016-07-15 15:02:24.071953"], ["updated_at", "2016-07-15 15:02:24.071953"]]
[1m[36m (0.2ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
Started GET "/login" for 127.0.0.1 at 2016-07-15 11:02:26 -0400
Processing by Users::SessionsController#new as HTML
Rendered users/sessions/_new.html.erb (75.4ms)
Rendered users/sessions/new.html.erb within layouts/application (82.6ms)
Rendered layouts/_shim.html.erb (0.2ms)
Rendered application/_favicon.html.erb (1.2ms)
Rendered users/sessions/_new.html.erb (8.2ms)
Rendered partners/sessions/_new.html.erb (16.3ms)
Rendered layouts/_header.html.erb (27.6ms)
Rendered layouts/_footer.html.erb (1.2ms)
Rendered layouts/_google_analytics.html.erb (1.0ms)
Completed 200 OK in 206ms (Views: 190.7ms | ActiveRecord: 0.0ms)
Started POST "/login" for 127.0.0.1 at 2016-07-15 11:02:28 -0400
Processing by Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "user"=>{"email"=>"test_user#example.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
This is where it hung. The rest of the log appeared after the test timed out.
[1m[35m (0.5ms)[0m ALTER TABLE "active_admin_comments" DISABLE TRIGGER ALL;ALTER TABLE "authorizations" DISABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" DISABLE TRIGGER ALL;ALTER TABLE "garagepartners" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "cars" DISABLE TRIGGER ALL;ALTER TABLE "locations" DISABLE TRIGGER ALL;ALTER TABLE "partners" DISABLE TRIGGER ALL;ALTER TABLE "appointments" DISABLE TRIGGER ALL;ALTER TABLE "images" DISABLE TRIGGER ALL;ALTER TABLE "garages" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL;ALTER TABLE "companies" DISABLE TRIGGER ALL;ALTER TABLE "damages" DISABLE TRIGGER ALL;ALTER TABLE "admin_users" DISABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" DISABLE TRIGGER ALL
[1m[36m (45.9ms)[0m [1mTRUNCATE TABLE "public"."active_admin_comments", "public"."authorizations", "public"."authorized_drivers", "public"."garagepartners", "public"."cars", "public"."locations", "public"."partners", "public"."appointments", "public"."images", "public"."garages", "public"."users", "public"."companies", "public"."damages", "public"."admin_users", "public"."delayed_jobs" RESTART IDENTITY CASCADE;[0m
[1m[35m (0.8ms)[0m ALTER TABLE "active_admin_comments" ENABLE TRIGGER ALL;ALTER TABLE "authorizations" ENABLE TRIGGER ALL;ALTER TABLE "authorized_drivers" ENABLE TRIGGER ALL;ALTER TABLE "garagepartners" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "cars" ENABLE TRIGGER ALL;ALTER TABLE "locations" ENABLE TRIGGER ALL;ALTER TABLE "partners" ENABLE TRIGGER ALL;ALTER TABLE "appointments" ENABLE TRIGGER ALL;ALTER TABLE "images" ENABLE TRIGGER ALL;ALTER TABLE "garages" ENABLE TRIGGER ALL;ALTER TABLE "users" ENABLE TRIGGER ALL;ALTER TABLE "companies" ENABLE TRIGGER ALL;ALTER TABLE "damages" ENABLE TRIGGER ALL;ALTER TABLE "admin_users" ENABLE TRIGGER ALL;ALTER TABLE "delayed_jobs" ENABLE TRIGGER ALL
This was in the Spork console after the test timed out:
1.1) Failure/Error: click_button 'Sign in'
Net::ReadTimeout:
Net::ReadTimeout
users/sessions_controller.rb (using Devise)
class Users::SessionsController < Devise::SessionsController
include ApplicationHelper
def create
super
end
def new
render 'new'
end
def after_sign_in_path_for(resource)
user_path(resource)
end
end
Got stuck at this point when stepping through the controller using byebug:
in /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/devise-3.5.6/app/controllers/devise/sessions_controller.rb
12: respond_with(resource, serialize_options(resource))
13: end
14:
15: # POST /resource/sign_in
16: def create
=> 17: self.resource = warden.authenticate!(auth_options)
After stepping into that, I got stuck here:
in /Users/JAckerman/.rvm/gems/ruby-2.2.4/gems/warden-1.2.6/lib/warden/proxy.rb
122: # Example
123: # env['warden'].authenticate!(:password, :scope => :publisher) # throws if it cannot authenticate
124: #
125: # :api: public
126: def authenticate!(*args)
=> 127: user, opts = _perform_authentication(*args)
128: throw(:warden, opts) unless user
129: user
130: end
After pulling out a lot of hair, this is what ended up working:
Change:
# configure database cleaner
config.before(:suite) do
DatabaseCleaner.start
DatabaseCleaner.clean_with(:truncation)
end
To:
# configure database cleaner
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
And add config.use_transactional_fixtures = false to rails_helper.rb, which had been there at the beginning and had been removed at some point in the many iterations of configurations that I had tried.
Either way, hopefully this saves someone else a headache!

Validation for uniqueness not working

I have a model called as Template which has self referential has-many through association with a join model called as RelatedTemplate.
The Template model is written like this:
has_many :related_templates, :foreign_key => :parent_id
has_many :children, :through => :related_templates, :source => :child
has_many :inverse_related_templates, class_name: "RelatedTemplate", :foreign_key => :child_id
has_many :parents, :through => :inverse_related_templates, :source => :parent
validates :name, presence: true, uniqueness: { case_sensitive: false },
length: { maximum: 100, too_long: "should be maximum %{count} characters" }
The join-model RelatedTemplate is:
belongs_to :parent, class_name: 'Template'
belongs_to :child, class_name: 'Template'
In the console when i tried to create a child template with the same name as the parent name then the validation doesn't work:
rails c --sandbox
Loading development environment in sandbox (Rails 4.2.5)
Any modifications you make will be rolled back on exit
irb(main):001:0> a = Template.new
=> #<Template id: nil, client_id: nil, something_id: nil, name: nil, description: nil, another_something_id: nil, video_id: nil, container_id: nil>
irb(main):002:0> a.something_id=1
=> 1
irb(main):003:0> a.name="Hamza"
=> "Hamza"
irb(main):004:0> a.another_something_id=16
=> 16
irb(main):005:0> a.container_id=2
=> 2
irb(main):006:0> a.children.build(name: "Hamza", another_something_id: 16, container_id: 2)
=> #<Template id: nil, client_id: nil, something_id: nil, name: "Hamza", description: nil, another_something_id: 16, video_id: nil, container_id: 2>
irb(main):007:0> a.save
(0.9ms) SAVEPOINT active_record_1
Template Exists (1.3ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.7ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
Template Exists (0.5ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.2ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
SQL (0.3ms) INSERT INTO "templates" ("something_id", "name", "another_something_id", "container_id") VALUES ($1, $2, $3, $4) RETURNING "id" [["something_id", 1], ["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
SQL (0.2ms) INSERT INTO "templates" ("name", "another_something_id", "container_id") VALUES ($1, $2, $3) RETURNING "id" [["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
SQL (0.6ms) INSERT INTO "related_templates" ("parent_id", "child_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["parent_id", 156], ["child_id", 157], ["created_at", "2016-05-05 07:03:51.496346"], ["updated_at", "2016-05-05 07:03:51.496346"]]
(0.2ms) RELEASE SAVEPOINT active_record_1
=> true
Now the query:
irb(main):016:0> a.name
=> "Hamza"
irb(main):017:0> a.children.first.name
Template Load (1.9ms) SELECT "templates".* FROM "templates" INNER JOIN "related_templates" ON "templates"."id" = "related_templates"."child_id" WHERE "related_templates"."parent_id" = $1 ORDER BY "templates"."id" ASC LIMIT 1 [["parent_id", 158]]
=> "Hamza"
Dont know what is wrong here ?
Both object only exist in memory, when you validate them. The uniqueness validation passes in both cases, because the validation checks if there is a similar record in the database already.
Have a look at the logs:
# you call save
irb(main):007:0> a.save
(0.9ms) SAVEPOINT active_record_1
# Rails validates the first object
Template Exists (1.3ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.7ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
# Rails validates the second object
Template Exists (0.5ms) SELECT 1 AS one FROM "templates" WHERE LOWER("templates"."name") = LOWER('Hamza') LIMIT 1
Container Load (0.2ms) SELECT "containers".* FROM "containers" WHERE "containers"."id" = $1 LIMIT 1 [["id", 2]]
# At this point Rails thinks that both records will be fine, because the validation passed
# Rails saved the first object
SQL (0.3ms) INSERT INTO "templates" ("something_id", "name", "another_something_id", "container_id") VALUES ($1, $2, $3, $4) RETURNING "id" [["something_id", 1], ["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
# Rails saved the second object
SQL (0.2ms) INSERT INTO "templates" ("name", "another_something_id", "container_id") VALUES ($1, $2, $3) RETURNING "id" [["name", "Hamza"], ["another_something_id", 16], ["container_id", 2]]
This is good example why Rails uniqueness validations are not 100% secure. Another example might be race conditions, when multiple requests hit the application at the same time.
The only way to avoid this kind of problems, is to add a unique index to the database table.

ruby on rails - Unique multiple key index issue in production (Heroku PostgreSQL)

I am facing an issue I have tried to solve by myself but I don't get what's wrong. I am French so my models, controllers... have french names.
I am developing an app for an association that makes what we call in French "maraudes" every night : driving around to meet people.
I have this Maraude model :
class Maraude < ActiveRecord::Base
default_scope -> { order(date: :desc) }
validates :date, presence: true,
uniqueness: { scope: :type_maraude }
validates :type_maraude, presence: true
end
My maraudes have :date and :type_maraude attributes, and I want them to define every maraude, so that every maraude has a unique [:date, :type_maraude] combination.
In order to do this, I also created this migration :
class AddIndexToMaraudes < ActiveRecord::Migration
def change
add_index :maraudes, [:date, :type_maraude], unique: true
end
end
It is perfectly working in development. In production (Heroku), I have created a maraude dated 2016-02-02 with a certain type (Maraude salariés 1) and when trying to create an other maraude at the same date but with a different type I get the following error and I don't understand where it may come from :
2016-02-05T13:56:51.810031+00:00 app[web.1]: Started POST "/maraudes" for 80.13.244.250 at 2016-02-05 13:56:51 +0000
2016-02-05T13:56:51.823195+00:00 app[web.1]: Maraude Exists (0.9ms) SELECT 1 AS one FROM "maraudes" WHERE ("maraudes"."date" = '2016-02-02' AND "maraudes"."type_maraude" = 'Maraude bénévoles') LIMIT 1
2016-02-05T13:56:51.812447+00:00 app[web.1]: Processing by MaraudesController#create as HTML
2016-02-05T13:56:51.829572+00:00 app[web.1]: Completed 500 Internal Server Error in 17ms (ActiveRecord: 5.9ms)
2016-02-05T13:56:51.819326+00:00 app[web.1]: Maraude Load (0.9ms) SELECT "maraudes".* FROM "maraudes" WHERE "maraudes"."date" = $1 AND "maraudes"."type_maraude" = $2 ORDER BY "maraudes"."date" DESC LIMIT 1 [["date", "2016-02-02"], ["type_maraude", "Maraude bénévoles"]]
2016-02-05T13:56:51.812533+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"useo/o+NPJ6cemrRfdUN2LRIsDCAHiseYTlV2EKXigH/6C47ZzEhtM0mCra7EuY/QY/nZuXdpfnTDxR4VugUdw==", "maraude"=>{"date"=>"2016-02-02", "type_maraude"=>"Maraude bénévoles"}, "commit"=>"Créer la maraude"}
2016-02-05T13:56:51.828110+00:00 app[web.1]: DETAIL: Key (date)=(2016-02-02) already exists.
2016-02-05T13:56:51.814745+00:00 app[web.1]: User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
2016-02-05T13:56:51.820512+00:00 app[web.1]: (0.7ms) BEGIN
2016-02-05T13:56:51.828073+00:00 app[web.1]: SQL (1.6ms) INSERT INTO "maraudes" ("date", "type_maraude", "villes", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["date", "2016-02-02"], ["type_maraude", "Maraude bénévoles"], ["villes", ""], ["created_at", "2016-02-05 13:56:51.823377"], ["updated_at", "2016-02-05 13:56:51.823377"]]
2016-02-05T13:56:51.828108+00:00 app[web.1]: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_maraudes_on_date"
2016-02-05T13:56:51.828111+00:00 app[web.1]: : INSERT INTO "maraudes" ("date", "type_maraude", "villes", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
2016-02-05T13:56:51.829215+00:00 app[web.1]: (0.9ms) ROLLBACK
2016-02-05T13:56:51.832064+00:00 app[web.1]:
2016-02-05T13:56:51.832067+00:00 app[web.1]: ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_maraudes_on_date"
2016-02-05T13:56:51.832068+00:00 app[web.1]: DETAIL: Key (date)=(2016-02-02) already exists.
2016-02-05T13:56:51.832069+00:00 app[web.1]: : INSERT INTO "maraudes" ("date", "type_maraude", "villes", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"):
2016-02-05T13:56:51.832070+00:00 app[web.1]: app/controllers/maraudes_controller.rb:34:in `create'
The PG error seems to indicate that it behaves like I had created a unique index on :date which is not the case...
For info here is my 'create' action in my Maraudes controller.
EDIT : I translated the flash messages.
def create
#maraude = Maraude.new(maraude_params)
#maraude.villes = ""
if Maraude.find_by(date: params[:maraude][:date], type_maraude: params[:maraude][:type_maraude])
flash[:danger] = "This maraude already exists"
redirect_to new_maraude_path
elsif #maraude.save
flash[:success] = "Maraude created"
redirect_to id_m_villes_path(id: #maraude.id)
else
flash[:danger] = "Give date and maraude type"
redirect_to new_maraude_path
end
end
Thx for your help !

creation of a nested_attributes makes before_create not work

I'm tried to create a User in the console doing:
2.2.1 :012 > u.save!
(0.2ms) BEGIN
User Exists (0.7ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('noc#co.co') LIMIT 1
SQL (2.1ms) INSERT INTO "users" ("id", "first_name", "last_name", "email", "title", "time_zone", "company_id", "password_digest", "created_at", "updated_at", "activation_digest") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["id", 200], ["first_name", "Random"], ["last_name", "Dude"], ["email", "noc#co.co"], ["title", "CEO"], ["time_zone", "Stockholm"], ["company_id", 1], ["password_digest", "$2a$10$bHHA/JP5IMrucGUXRWMpsO8sInaouSqn48M.fDHpjGdvedu3Napra"], ["created_at", "2015-10-11 23:09:38.213109"], ["updated_at", "2015-10-11 23:09:38.213109"], ["activation_digest", "$2a$10$WF3bUOtbC1gk4ZnX58cJZO5k7P7YV6wvhmwz7EErTdvIseNuy0oyq"]]
2.2.1 :013 > u.activation_token
=> "vKrs0jtvZRiyU-YVE-aPXw"
now when I try to create a user the before_create doesn't work, I tried changing it to before_validation and that didn't work either.
The user is a nested attribute from companies, and is created in Companies#new.
class User < ActiveRecord::Base
belongs_to :company
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
now when I do #user.activation_token it returns nil. Here's the console log from when I try it on the app:
Started POST "/companies" for ::1 at 2015-10-12 01:31:47 +0200
Processing by CompaniesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZTEtGR2Dd1FDDYm9j4/SiqSTP646R8gctFx4aJHM9QDP+RQky8SG6gkomLbf+E+LgMi+aah1YOhCkUsg3uSYoQ==", "company"=>{"time_zone"=>"Stockholm", "users_attributes"=>{"0"=>{"first_name"=>"swaga", "last_name"=>"swaga", "email"=>"swaga#wkoa.com", "password"=>"[FILTERED]"}}, "name"=>"swaga"}, "commit"=>"Create Company"}
(0.2ms) BEGIN
User Exists (1.3ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('swaga#wkoa.com') LIMIT 1
SQL (7.1ms) INSERT INTO "companies" ("name", "time_zone", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "swaga"], ["time_zone", "Stockholm"], ["created_at", "2015-10-11 23:31:47.380530"], ["updated_at", "2015-10-11 23:31:47.380530"]]
SQL (0.5ms) INSERT INTO "users" ("first_name", "last_name", "email", "password_digest", "activation_digest", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["first_name", "swaga"], ["last_name", "swaga"], ["email", "swaga#wkoa.com"], ["password_digest", "$2a$10$3GsPACTg5HPodiqdedsCvu52N64BEE3/fA77p.oBHAhM51zCSzUV."], ["activation_digest", "$2a$10$75y9jP.eZxmWI1KjHZrg3.DuB5GSwiS2UsaQdtV25ClBHDi.z4Pte"], ["company_id", 8], ["created_at", "2015-10-11 23:31:47.390462"], ["updated_at", "2015-10-11 23:31:47.390462"]]
(6.7ms) COMMIT
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."company_id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["company_id", 8]]
Rendered user_mailer/account_activation.html.erb within layouts/mailer (7.8ms)
UserMailer#account_activation: processed outbound mail in 29.2ms
Completed 500 Internal Server Error in 380ms (ActiveRecord: 16.9ms)
ActionController::UrlGenerationError - No route matches {:action=>"edit", :controller=>"account_activations", :email=>"swaga#wkoa.com", :id=>nil} missing required keys: [:id]:
now I see that the activation_digest is returned, so I think the issue is literarily just the before_create not working? Which is weird because then it shouldn't be able to create an activation digest as the two are connected:
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
Your error says:
ActionController::UrlGenerationError - No route matches {:action=>"edit", :controller=>"account_activations", :email=>"swaga#wkoa.com", :id=>nil} missing required keys: [:id]:
Seems like, in your view, you are calling edit_account_activation_path without the id param and that's creating the problem for you. Try to send the user.id as a parameter in the edit_account_activation_path call.
Something like this:
edit_account_activation_path(user.email, user.id)
That should fix your issue.

Resources