# ActiveRecord 'find\_or\_initialize\_by' dynamic finder bug? Ignoring conditions

**URL:** <https://www.ruby-forum.com/t/activerecord-find-or-initialize-by-dynamic-finder-bug-ignoring-conditions/128360>\
**Category:** Rails\
**Created:** [February 7, 2008, 2:13am UTC](https://www.ruby-forum.com/t/activerecord-find-or-initialize-by-dynamic-finder-bug-ignoring-conditions/128360 "2008-02-07T02:13:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 7, 2008, 2:13am UTC](https://www.ruby-forum.com/t/activerecord-find-or-initialize-by-dynamic-finder-bug-ignoring-conditions/128360/1 "2008-02-07T02:13:31Z")

</div>

Hello all,

I just ran into something that I think is a bug, and I would like to  
confirm with the core team whether this is expected/desired behavior  
or if this is a bug that I should file and develop failing tests for  
(I doubt I have the active record method\_missing fu to actually patch  
it).

Test Scenario:  
I would like to find or initialize a new user and base the find on the  
users email address, however the user found has to also match one of  
two possible ‘state’ values (passive || pending\_singup). While trying  
to implement this I discovered that the find\_or\_(initialize|  
create)_by_\* dynamic finders totally and silently ignore any  
conditions passed.

Bug?

Should’nt these dynamic finders behave the same as find\_by\_\* or  
find\_all\_by\_\* dynamic finders and use the :conditions passed to them?  
The documentation seems to indicate that they should.

> **[ActiveRecord::Base](https://api.rubyonrails.org/classes/ActiveRecord/Base.html)**
>
> Active Record Active Record objects don't specify their attributes directly, but rather infer them from the table definition with which they're linked.

Dynamic attribute-based finders

“It’s even possible to use all the additional parameters to find. For  
example, the full interface for Payment.find\_all\_by\_amount is actually  
Payment.find\_all\_by\_amount(amount, options). And the full interface to  
Person.find\_by\_user\_name is actually  
Person.find\_by\_user\_name(user\_name, options). So you could call  
Payment.find\_all\_by\_amount(50, :order =\> “created\_on”).  
The same dynamic finder style can be used to create the object if it  
doesn’t already exist. This dynamic finder is called with  
find\_or\_create\_by\_ and will return the object if it already exists and  
otherwise creates it, then returns it.”

Here are a couple of examples. I know these are contrived since I  
could use ‘find\_or\_initialize\_by\_name\_and\_state()’ however what I am  
really trying to show is that the :conditions options are ignored.  
Check out the actual SQL run by each of these finds in a console to  
see what I mean.

## EXAMPLE : USES CONDITIONS

> > @user = User.find\_by\_email(‘removed\_email\_address@domain.invalid’, :conditions =\> {:state =\> ‘passive’})  
> > User Load (0.000426) SELECT \* FROM `users` WHERE (`users`.`email`  
> > = ‘removed\_email\_address@domain.invalid’) AND (`users`.`state` = ‘passive’) LIMIT 1  
> > =\> nil

> > > > @user = User.find\_all\_by\_email(‘removed\_email\_address@domain.invalid’, :conditions =\> {:state =\> ‘passive’})  
> > > > User Load (0.000425) SELECT \* FROM `users` WHERE (`users`.`email`  
> > > > = ‘removed\_email\_address@domain.invalid’) AND (`users`.`state` = ‘passive’)  
> > > > =\> []

## EXAMPLE : find\_or\_(create|initialize)_by_\* IGNORES CONDITIONS

> > @user = User.find\_or\_create\_by\_email(‘removed\_email\_address@domain.invalid’, :conditions =\> {:state =\> ‘passive’})  
> > User Load (0.000436) SELECT \* FROM `users` WHERE (`users`.`email`  
> > = ‘removed\_email\_address@domain.invalid’) LIMIT 1

> > @user = User.find\_or\_initialize\_by\_email(‘removed\_email\_address@domain.invalid’, :conditions =\> {:state =\> ‘passive’})  
> > User Load (0.000409) SELECT \* FROM `users` WHERE (`users`.`email`  
> > = ‘removed\_email\_address@domain.invalid’) LIMIT 1  
> > =\> #\<User id: 2, login: nil, email: “removed\_email\_address@domain.invalid”, crypted\_password:  
> > nil, salt: nil, created\_at: “2008-02-07 00:48:48”, updated\_at:  
> > “2008-02-07 00:48:48”, remember\_token: nil, remember\_token\_expires\_at:  
> > nil, activation\_code: nil, activated\_at: nil, state: “passive”,  
> > deleted\_at: nil, password\_reset\_at: nil, forgot\_password\_code: nil,  
> > name: nil, beta\_code: nil, beta\_approved\_at: nil\>

Thanks,

Glenn

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 7, 2008, 2:17am UTC](https://www.ruby-forum.com/t/activerecord-find-or-initialize-by-dynamic-finder-bug-ignoring-conditions/128360/2 "2008-02-07T02:17:37Z")

</div>

Here is a pastie of the samples I embedded here which will be easier  
to read perhaps.

[http://pastie.caboo.se/148479](http://pastie.caboo.se/148479)

Glenn
