Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails find_or_create_by where block runs in the find case?

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?

like image 614
Simon Woodside Avatar asked Mar 28 '11 15:03

Simon Woodside


2 Answers

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

like image 109
fl00r Avatar answered Sep 29 '22 09:09

fl00r


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!

like image 33
deivid Avatar answered Sep 29 '22 09:09

deivid