0

everyone!

I am not sure this is a bug, or something I am unaware of, but if I try to test joins() on AR tests,within Rails, using a different database, it just wont work. It seems to work on dev mode, console, but not on tests. So my tests fail. :(

Would you please let me know if I missed something about it here? Or maybe help me test and make sure this is a bug?

Ok, so the idea is this: I have 2 databases. And I have different set of models, for each database. In my example, lets suppose I have users and offices on both databases. So my YML file is this:

common: &common
  username: root
  password: 
  host: 127.0.0.1
  encoding: utf8
  adapter: mysql2

development:
  <<: *common
  database: scopetest_devel

test: &test
  <<: *common
  database: scopetest_test

other_development:
  <<: *common
  database: othertest_devel

other_test: &other_test
  <<: *common
  database: othertest_test

And here are the classes for my test

class User < ActiveRecord::Base

  attr_accessible :name, :office_id, :office
  belongs_to :office

end

class Office < ActiveRecord::Base

  attr_accessible :name
  has_many :users

end

class AnotherUser < ActiveRecord::Base

  establish_connection "other_#{Rails.env}"
  self.table_name = "users"

  attr_accessible :name, :office_id, :office
  belongs_to :office, class_name: "AnotherOffice"

end

class AnotherOffice < ActiveRecord::Base

  establish_connection "other_#{Rails.env}"
  self.table_name = "offices"

  attr_accessible :name
  has_many :users, class_name: "AnotherUser"

end

As you can see, they are identical. Except for the table they belong to, and database connection.

Now, this is my test file:

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  test "scoping works" do
    office = Office.create!(name: 'My Office')
    user = User.create!(office: office, name: 'John Doe')
    assert_equal 1, User.joins(:office).count
  end

  test "another db scoping doesnt" do 
    office = AnotherOffice.create!(name: 'My Office 2')
    user = AnotherUser.create!(office: office, name: 'John Doe')
    assert_equal 1, AnotherUser.joins(:office).count
  end
end

Now, surprisingly (maybe not to you), first test will pass. Second will fail. On console, though, if I create these models and perform joins(), it will work. Basically, any scope using joins on a different database, in test mode, will return 0 on count. Now, is this a bug? :( Anyone willing to test it too is welcome!

This is:

Rails 3.2.11 Ruby 1.9.3-p194

Gemfile.lock:

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (3.2.11)
      actionpack (= 3.2.11)
      mail (~> 2.4.4)
    actionpack (3.2.11)
      activemodel (= 3.2.11)
      activesupport (= 3.2.11)
      builder (~> 3.0.0)
      erubis (~> 2.7.0)
      journey (~> 1.0.4)
      rack (~> 1.4.0)
      rack-cache (~> 1.2)
      rack-test (~> 0.6.1)
      sprockets (~> 2.2.1)
    activemodel (3.2.11)
      activesupport (= 3.2.11)
      builder (~> 3.0.0)
    activerecord (3.2.11)
      activemodel (= 3.2.11)
      activesupport (= 3.2.11)
      arel (~> 3.0.2)
      tzinfo (~> 0.3.29)
    activeresource (3.2.11)
      activemodel (= 3.2.11)
      activesupport (= 3.2.11)
    activesupport (3.2.11)
      i18n (~> 0.6)
      multi_json (~> 1.0)
    arel (3.0.2)
    builder (3.0.4)
    coffee-rails (3.2.2)
      coffee-script (>= 2.2.0)
      railties (~> 3.2.0)
    coffee-script (2.2.0)
      coffee-script-source
      execjs
    coffee-script-source (1.4.0)
    erubis (2.7.0)
    execjs (1.4.0)
      multi_json (~> 1.0)
    hike (1.2.1)
    i18n (0.6.1)
    journey (1.0.4)
    jquery-rails (2.2.0)
      railties (>= 3.0, < 5.0)
      thor (>= 0.14, < 2.0)
    json (1.7.6)
    mail (2.4.4)
      i18n (>= 0.4.0)
      mime-types (~> 1.16)
      treetop (~> 1.4.8)
    mime-types (1.19)
    multi_json (1.5.0)
    mysql2 (0.3.11)
    polyglot (0.3.3)
    rack (1.4.4)
    rack-cache (1.2)
      rack (>= 0.4)
    rack-ssl (1.3.3)
      rack
    rack-test (0.6.2)
      rack (>= 1.0)
    rails (3.2.11)
      actionmailer (= 3.2.11)
      actionpack (= 3.2.11)
      activerecord (= 3.2.11)
      activeresource (= 3.2.11)
      activesupport (= 3.2.11)
      bundler (~> 1.0)
      railties (= 3.2.11)
    railties (3.2.11)
      actionpack (= 3.2.11)
      activesupport (= 3.2.11)
      rack-ssl (~> 1.3.2)
      rake (>= 0.8.7)
      rdoc (~> 3.4)
      thor (>= 0.14.6, < 2.0)
    rake (10.0.3)
    rdoc (3.12)
      json (~> 1.4)
    sass (3.2.5)
    sass-rails (3.2.6)
      railties (~> 3.2.0)
      sass (>= 3.1.10)
      tilt (~> 1.3)
    sprockets (2.2.2)
      hike (~> 1.2)
      multi_json (~> 1.0)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    thor (0.17.0)
    tilt (1.3.3)
    treetop (1.4.12)
      polyglot
      polyglot (>= 0.3.1)
    tzinfo (0.3.35)
    uglifier (1.3.0)
      execjs (>= 0.3.0)
      multi_json (~> 1.0, >= 1.0.2)

PLATFORMS
  ruby

DEPENDENCIES
  coffee-rails (~> 3.2.1)
  jquery-rails
  mysql2
  rails (= 3.2.11)
  sass-rails (~> 3.2.3)
  uglifier (>= 1.0.3)
tereško
  • 58,060
  • 25
  • 98
  • 150
marcelorocks
  • 2,005
  • 3
  • 18
  • 28

1 Answers1

4

Check your test configuration. I believe by default tests are executed within a SQL transaction that is rolled back. The transactions are going to be local to the database connection until they are committed.

Why is this causing your problem? You have a record added (in a transaction) in one db and are then trying to read that data from another connection (via your second DB adapter), however this data isn't visible yet because the transaction hasn't been committed.

When you execute the same code in a console, it is not wrapped in a transaction and is immediately committed and available.

You can try disabling transaction for this test by editing your test:

class UserTest < ActiveSupport::TestCase
  self.use_transactional_fixtures = false

  ...
Winfield
  • 18,985
  • 3
  • 52
  • 65
  • I will check that, however I dont see how the second test would need a connection / transaction with the first db adapter. The models in the second test are independent from the first, and the scope works between them. Am I wrong? – marcelorocks Feb 01 '13 at 21:51
  • You can verify that this is the cause by turning off transactions as described here: http://stackoverflow.com/questions/4055147/how-can-a-person-toggle-the-use-of-transactional-fixtures-for-one-set-of-tests-u – zetetic Feb 01 '13 at 23:01
  • Thank you, this was very useful. I will learn more about transactional fixtures :) – marcelorocks Feb 02 '13 at 11:25