Question

The ActiveRecord find_or_create_by dynamic finder method allows me to specify a block. The documentation isn't clear on this, but it seems that the block only runs in the create case, and not in the find case. In other words, if the record is found, the block doesn't run. I tested it with this console code:

User.find_or_create_by_name("An Existing Name") do |u|
  puts "I'M IN THE BLOCK"
end

(nothing was printed). Is there any way to have the block run in both cases?

Was it helpful?

Solution

As far as I understand block will be executed if nothing found. Usecase of it looks like this:

User.find_or_create_by_name("Pedro") do |u|
  u.money = 0
  u.country = "Mexico"
  puts "User is created"
end

If user is not found the it will initialized new User with name "Pedro" and all this stuff inside block and will return new created user. If user exists it will just return this user without executing the block.

Also you can use "block style" other methods like:

User.create do |u|
  u.name = "Pedro"
  u.money = 1000
end

It will do the same as User.create( :name => "Pedro", :money => 1000 ) but looks little nicer

and

User.find(19) do |u|
  ..
end

etc

OTHER TIPS

It doesn't seem to me that this question is actually answered so I will. This is the simplest way, I think, you can achieve that:

User.find_or_create_by_name("An Existing Name or Non Existing Name").tap do |u|
  puts "I'M IN THE BLOCK REGARDLESS OF THE NAME'S EXISTENCE"
end

Cheers!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top