Created
March 13, 2014 15:50
-
-
Save JoshDoody/9531033 to your computer and use it in GitHub Desktop.
Failing tests for Rails 4 unscoped when used with eager loading (includes). Two assertions should fail: Line 88 and Line 110. Line 88 should pass in Rails 3, but won't in Rails 4. Line 110 leverages the 'unscoped association' added in Rails 4, but still fails.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unless File.exist?('Gemfile') | |
File.write('Gemfile', <<-GEMFILE) | |
source 'https://rubygems.org' | |
gem 'rails', github: 'rails/rails' | |
gem 'arel', github: 'rails/arel' | |
gem 'sqlite3' | |
GEMFILE | |
system 'bundle' | |
end | |
require 'bundler' | |
Bundler.setup(:default) | |
require 'active_record' | |
require 'minitest/autorun' | |
require 'logger' | |
# This connection will do for database-independent bug reports. | |
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') | |
ActiveRecord::Base.logger = Logger.new(STDOUT) | |
ActiveRecord::Schema.define do | |
create_table :checklists do |t| | |
t.integer :tenant_id | |
end | |
create_table :submissions do |t| | |
t.integer :checklist_id | |
t.integer :tenant_id | |
end | |
create_table :tenants do |t| | |
end | |
end | |
class Checklist < ActiveRecord::Base | |
default_scope { where(tenant_id: Tenant.current_id) } | |
has_many :submissions | |
belongs_to :tenant | |
end | |
class Submission < ActiveRecord::Base | |
default_scope { where(tenant_id: Tenant.current_id) } | |
belongs_to :checklist | |
###### This unscoped association is my workaround in Rails 4 | |
###### You'll want comment out if testing in Rails 3 | |
belongs_to :unscoped_checklist, -> { unscope(where: :tenant_id) }, foreign_key: :checklist_id, class_name: "Checklist" | |
belongs_to :tenant | |
end | |
class Tenant < ActiveRecord::Base | |
cattr_accessor :current_id | |
has_many :checklists | |
has_many :submissions | |
end | |
class BugTest < Minitest::Test | |
def test_association_stuff | |
tenant = Tenant.create! | |
checklist = Checklist.create!(tenant_id: tenant.id) | |
submission = Submission.create!(tenant_id: tenant.id, checklist_id: checklist.id) | |
s = nil | |
c = nil | |
Tenant.current_id = tenant.id | |
assert_equal 1, Submission.count | |
assert_equal 1, Checklist.count | |
assert_equal 1, Checklist.first.submissions.count | |
assert_equal checklist.id, Submission.first.checklist.id | |
Tenant.current_id = nil | |
assert_equal 0, Checklist.count | |
assert_equal 0, Submission.count | |
assert_equal 1, Checklist.unscoped.count | |
assert_equal 1, Submission.unscoped.count | |
####### Should find submission and preload its checklist | |
Submission.unscoped { Checklist.unscoped { s = Submission.includes(:checklist).find(submission.id) }} | |
assert_equal submission.id, s.id | |
####### I believe this will pass in Rails 3.2.17, but fail in Rails 4 (undefined method 'id' for nil object) | |
assert_equal checklist.id, s.checklist.id | |
####### Everything below this line is Rails 4 specific | |
####### (relates to unscoped_checklist association on Submission class) | |
s = Submission.unscoped.find(submission.id) | |
assert_equal submission.id, s.id | |
####### This works... | |
assert_equal checklist.id, s.unscoped_checklist.id | |
####### This works (using an unscoped block explicitly) | |
s = Submission.unscoped.find(submission.id) | |
assert_equal submission.id, s.id | |
Checklist.unscoped do | |
c = s.checklist | |
end | |
assert_equal checklist.id, c.id | |
s = Submission.unscoped.includes(:unscoped_checklist).find(submission.id) | |
assert_equal submission.id, s.id | |
###### This doesn't... The 'unscoped' call actually defeats the preloaded unscoped association | |
###### The default_scope for the Checklist class is applied even though it's specifically | |
###### overriden in this assocation. | |
###### Also fails with 'preload' | |
assert_equal checklist.id, s.unscoped_checklist.id | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment