DEV Community

Discussion on: FactoryBot .find_or_create_by

Collapse
 
jooeycheng profile image
Joey Cheng • Edited

Hey Roland!

Firstly, apologies for the late reply. πŸ™πŸ»
I'm happy that the article helped you!

If I understand your requirements correctly - you want to be able to find_by "country code", but create with random "inhabitants". Something lesser known in Rails - there is a method exactly just for that:

FactoryBot.define do
  factory :country do
    name { 'Canada' }
    code { 'CA' }
    inhabitants { SecureRandom.rand(10..100_000_000) }

    to_create do |instance|
      instance.id = Country.create_with(name: instance.name, inhabitants: instance.inhabitants)
                           .find_or_create_by!(code: instance.code)
                           .id
      instance.reload
    end
  end
end

This would find_by "code", and return if exists. Else, it will create with "code", along with "name" and "inhabitants".

I wrote that off the top of my mind. Can you test to make sure it works?

Collapse
 
agrinko profile image
Alexey Grinko

I solved it a bit differently:

  instance.id = Country.where(code: instance.code).first_or_create(instance.attributes).id
Enter fullscreen mode Exit fullscreen mode

Not sure if it makes any difference with your sample above, but using instance.attributes makes it more generic as we don't have to explicitly mention each attribute.

Thread Thread
 
jooeycheng profile image
Joey Cheng

That’s neat! Yeah, this does seem simpler. Off the top of my head, I can’t think of any differences.