save(validate: false)

Skip to first unread message

Danial Pearce

Aug 29, 2013, 9:20:32 AM8/29/13
Consider a simple User -> has_many -> Item, and of course Item ->
belongs_to -> User as the inverse.

Fabricator(:item) do
name 'thingy'

Fabricator(:user) do
name 'joe'
items(count: 1)

Now say we want to give that thingy to another user. I have a simple
model method called Item.give!(receiver) which will do it:

def give!(receiver)
self.user_id = false)

I had the validate: false in there because if validations change in
future and there is invalid data or something, I still want to be able
to "give!" items to other users.

Anyway, I wrote a simple test for this:

joe = Fabricate(:user)
tom = Fabricate(:user, name: 'tom')
item = joe.items.first

# force reload from database
item = Item.find(
tom = User.find(
joe = User.find(

assert item.user_id ==
assert tom.items.size == 2
assert joe.items.size == 0

Alas, the test fails at the first assertion, even though the model
code works fine outside of Fabricator. However, if I remove the
validate: false in the model method, the test passes.

Also if I change the model to do "self.user = receiver.user" Instead
of setting the _id directly, it also works, i.e. I can leave the
validate: false in place.

Item has a validates_presence_of :user on Item if that makes any
difference. Pretty confusing that some trivial changes in the model
fix the test, and unfortunately the test fails on what is code that
actually works :(

Not sure if I've uncovered a bug, or just using rails nuances that
fabrication gem doesn't like, such as setting the _id of an
association without also setting the association along with it.
ActiveRecord deals with it fine outside of Fabricator, but inside
Fabricator it seems changing the ID of an association directly does
not trigger any update on the database.

Paul Elliott

Aug 29, 2013, 9:34:14 AM8/29/13
The nuances you are uncovering have to do with ActiveRecord. Fabrication sets attributes on models the same way you would in a controller. These issues have to do with the way ActiveRecord sets the user vs the user_id, which are separate attrs in your model. What you are describing happens because if you set the user_id directly, then the user attr won't be present automatically. If you change your `give` method to set the receiver instead of the underlying ids then it should work. Alternatively, you could try changing the validation from user to user_id, which is what you are ultimately trying to verify anyway.

-- Paul

You received this message because you are subscribed to the Google Groups "fabrication" group.
To unsubscribe from this group and stop receiving emails from it, send an email to

Reply all
Reply to author
0 new messages