8

FactoryGirl won't set my protected attribute user.confirmed. What's the best practice here?

Factory.define :user do |f|
  f.name "Tim"          # attr_accessible -- this works
  f.confirmed true      # attr_protected -- doesn't work
end 

I can do a @user.confirmed = true after using my factory, but that's a lot of repetition across a lot of tests.

iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
brittohalloran
  • 3,534
  • 4
  • 28
  • 27

3 Answers3

10

Using an after_create hook works:

Factory.define :user do |f|
  f.name "Tim"
  f.after_create do |user|
    user.confirmed = true
    user.save
  end
end 
brittohalloran
  • 3,534
  • 4
  • 28
  • 27
  • 2
    Great find. More recent of versions of factory girl changed the syntax to `after(:create)`. See [getting started guide](https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md) – Jason Kim Mar 19 '13 at 00:55
3

You would have to pass it into the hash when you create the user since FactoryGirl is protecting it from mass-assignment.

user ||= Factory(:user, :confirmed => true)
iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
0

Another approach is to use Rails' built in roles like this:

#user.rb
attr_accessor :confirmed, :as => :factory_girl

When mass-assigning FactoryGirl broadcasts this role, making this pattern possible.

Pros: Keeps factories fast, simple, and clean (less code in callbacks)
Cons: You are changing your model code for your tests :(

Some untested suggestions to address the Con:

  • You could re-open the class just above your factory.
  • You could re-open the class in a [test|spec]_helper
Chip
  • 195
  • 1
  • 4