paulelliott/fabrication — Issue #71: Lazy-loaded associations don't work with :validates_presence_of
Author: urbanautomaton
Created: 2011-11-10 13:41:18+00:00
State: open

Hi,

I'm having problems where lazy-loaded associations that are the subject of a `validates_presence_of` validation are failing to work - validation fails, and the association returns nil.

Basic example to reproduce (sorry - will try to make time to submit a failing test later):

# Models
class Network < ActiveRecord::Base; end
class Merchant < ActiveRecord::Base
belongs_to :network
validates_presence_of :network
end

# Fabricators
Fabricator(:network)
Fabricator(:merchant) { network }

# merchant_spec.rb
describe Merchant do
let(:merchant) { Fabricate(:merchant) }

it "is valid" do
merchant.should be_valid
end

it "has a network" do
merchant.network.should be_present
end
end

Both of these tests fail with the validation in place. If the validation is removed, they both pass.

I can see there's something fiendishly clever going on in `Generator::ActiveRecord` to overwrite the association accessor. I can't, however, figure out why a) the `#save!` call doesn't throw an exception (the instance is, after all, invalid by its own insistence), and why subsequent calls to the association accessor don't cause the stored proc to fire.

Bizarrely, when I did the following (to let me check that the accessor overwriting was actually happening):

class Merchant < ActiveRecord::Base
belongs_to :network
validates_presence_of :network

def network_with_debugger
network_without_debugger
debugger
end
alias_method_chain :network, :debugger
end

...then both tests pass even if I don't actually do anything in the debugger session. I can see the proc stored in `@__network_block`, and call it without problems.

All very odd.