# ActiveRecord.id does not work within named\_scope block

**URL:** <https://www.ruby-forum.com/t/activerecord-id-does-not-work-within-named-scope-block/146196>\
**Category:** Rails\
**Created:** [August 19, 2008, 12:22am UTC](https://www.ruby-forum.com/t/activerecord-id-does-not-work-within-named-scope-block/146196 "2008-08-19T00:22:27Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Swartz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/90db22/32.png) [@Swartz](https://www.ruby-forum.com/u/Swartz)\
**Post date:** [August 19, 2008, 12:22am UTC](https://www.ruby-forum.com/t/activerecord-id-does-not-work-within-named-scope-block/146196/1 "2008-08-19T00:22:27Z")

</div>

Hi,

Trying to create a named\_scope that would check that the record is not  
itself.

I have companies and contacts, where a contact can be a primary  
contact for a company:

class Company  
has\_many :contacts  
end

class Contact \< ActiveRecord::Base  
belongs\_to :company

named\_scope :primary, :conditions =\> { :is\_primary =\> true } do  
def mark\_as\_non\_primary!  
each { |p| p.update\_attribute(:is\_primary, false) }  
end  
end

named\_scope :but\_not\_itself, :conditions =\> [‘contacts.id != ?’,  
id]  
end

So I would like to do something like this from Contact model:

company.contacts.primary.but\_not\_itself.mark\_as\_non\_primary!

However this does not work because id method within but\_not\_itself  
named\_scope returns an Object.id (instance id) and not ActiveRecord id  
(database id).

How do I make it work?

Thanks!

---

<div class="post-metadata">

**Author:** ![Swartz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/90db22/32.png) [@Swartz](https://www.ruby-forum.com/u/Swartz)\
**Post date:** [August 19, 2008, 1:05am UTC](https://www.ruby-forum.com/t/activerecord-id-does-not-work-within-named-scope-block/146196/2 "2008-08-19T01:05:09Z")

</div>

On Aug 18, 11:21 pm, Swartz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> named\_scope :but\_not\_itself, :conditions =\> [‘contacts.id != ?’,

The reason this does not work is because that expression “id” is  
evaluated when named\_scope is call to create the scope, ie when the  
class is loaded, so self is the class Contact.  
It’s the same reason why doing :conditions =\> [‘created\_at \< ?’,  
1.day.ago] won’t work properly: the 1.day.ago is evaluated once, at  
class load time and then never again.

Luckily instead of passing a hash of options you can pass a lambda  
that returns a hash of options. Since that proc will be called when  
the scope is loaded and in the right context you should be fine.

Fred

---

<div class="post-metadata">

**Author:** ![Swartz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/90db22/32.png) [@Swartz](https://www.ruby-forum.com/u/Swartz)\
**Post date:** [August 19, 2008, 3:12am UTC](https://www.ruby-forum.com/t/activerecord-id-does-not-work-within-named-scope-block/146196/3 "2008-08-19T03:12:02Z")

</div>

Hi Fred,

Thanks for your input.

So far I changed that named\_scope into this:  
named\_scope :but\_not\_itself,  
lambda { |id| { :conditions =\> [‘contacts.id != ?’, id]} }

Is that what you meant?

Is there a better way to do this?

Now I have to do this:  
company.contacts.primary.but\_not\_itself(self.id).mark\_as\_non\_primary!

seems, to me at least, kind of ugly having to pass self.id… 🙂

By the way my inspiration for this came from  
[http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality](http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality)  
Where the author has User.inactive.activate to very neatly activate  
inactive users.

–  
Swartz

On Aug 18, 5:04 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
