# Method\_missing error when caching an ActiveRecord model

**URL:** <https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738>\
**Category:** Rails\
**Created:** [August 21, 2006, 1:23am UTC](https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738 "2006-08-21T01:23:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brittain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/4491bb/32.png) [@Brittain](https://www.ruby-forum.com/u/Brittain)\
**Post date:** [August 21, 2006, 1:23am UTC](https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738/1 "2006-08-21T01:23:47Z")

</div>

I have a simple singleton cache that stores ActiveRecord model objects  
for me so I’m not constantly hitting the DB for static data. This was  
working great until I tried to add a method (any method really) to the  
model, e.g:

class Tag \<\< ActiveRecord::Base  
def is\_main?  
logger.debug(“is\_main?”)  
return some\_attribute && some\_other\_attribute  
end  
end

This method works fine when called from a unit test:

def test\_is\_main  
tags = Tag.find\_menus("\_\_none")  
tags.each {|t|  
# Hit an accessor works fine  
assert t.is\_menu?  
# Hit my method works fine  
assert t.is\_main?  
}  
end

But if I pull the tag from the cache, the attributes are all there, but  
the is\_main? call gives method\_missing, eg:

def index  
home\_page = MenuCache.home\_page  
home\_page2 = Tag.find\_by\_id(14)  
logger.debug(“ConvsController.index(#{home\_page.inspect})”)  
logger.debug(“ConvsController.index(#{home\_page2.inspect})”)

```
home_page2.is_main?
home_page.is_main # <= line #37

```

end

Yields (before logging edited):

Tag Load (0.010000) SELECT \* FROM tags WHERE (tags.`id` = 14 )  
LIMIT 1

ConvsController.index(#\<Tag:0x6a69f30 @attributes={“name”=\>“Home”,  
“updated\_at”=\>“2006-08-19 15:11:56”, “a\_key”=\>"\_\_home",  
“parent\_menu”=\>"\_\_none", “created\_by”=\>“1”, “a\_controller”=\>"/pages",  
“is\_login\_needed”=\>“0”, “id”=\>“14”, “list\_view”=\>“no\_pref”,  
“show\_view”=\>“no\_pref”, “an\_action”=\>“index”, “deletable”=\>“0”,  
“inherit\_security\_from”=\>nil, “ordering”=\>“root\_id DESC, lft”,  
“position”=\>“1”, “is\_menu”=\>“1”, “created\_at”=\>“2006-08-19 15:11:56”}\>)

ConvsController.index(#\<Tag:0x6796150 @attributes={“name”=\>“Home”,  
“updated\_at”=\>“2006-08-19 15:11:56”, “a\_key”=\>"\_\_home",  
“parent\_menu”=\>"\_\_none", “created\_by”=\>“1”, “a\_controller”=\>"/pages",  
“is\_login\_needed”=\>“0”, “id”=\>“14”, “list\_view”=\>“no\_pref”,  
“show\_view”=\>“no\_pref”, “an\_action”=\>“index”, “deletable”=\>“0”,  
“inherit\_security\_from”=\>nil, “ordering”=\>“root\_id DESC, lft”,  
“position”=\>“1”, “is\_menu”=\>“1”, “created\_at”=\>“2006-08-19 15:11:56”}\>)

is\_main?()

NoMethodError (undefined method `is\_main?’ for #Tag:0x6a69f30):

C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/base.rb:1792:in  
`method_missing' /app/controllers/pages_controller.rb:37:in`index’

So where did my method disappear to?

Thanks in advance, Brittain

---

<div class="post-metadata">

**Author:** ![Brittain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/4491bb/32.png) [@Brittain](https://www.ruby-forum.com/u/Brittain)\
**Post date:** [August 21, 2006, 1:37am UTC](https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738/2 "2006-08-21T01:37:48Z")

</div>

Hi~

On Aug 20, 2006, at 4:02 PM, Brittain wrote:

> end  
> assert t.is\_main?  
> logger.debug(“ConvsController.index(#{home\_page.inspect})”)
> 
> “updated\_at”=\>“2006-08-19 15:11:56”, “a\_key”=\>"\_\_home",  
> NoMethodError (undefined method `is\_main?’ for #Tag:0x6a69f30):
> 
> C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/  
> active\_record/base.rb:1792:in  
> `method_missing' /app/controllers/pages_controller.rb:37:in`index’
> 
> So where did my method disappear to?
> 
> Thanks in advance, Brittain

```
Can you show your caching code? How are you storing items in the

```

cache? Are you using marshal? Also if you run more then one mongrel  
or fcgi how will you make sure that you always get the same cache  
object to work with?

-Ezra

---

<div class="post-metadata">

**Author:** ![Brittain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/4491bb/32.png) [@Brittain](https://www.ruby-forum.com/u/Brittain)\
**Post date:** [August 21, 2006, 2:21am UTC](https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738/3 "2006-08-21T02:21:49Z")

</div>

Ezra Z. wrote:

> > class Tag \<\< ActiveRecord::Base  
> > tags.each {|t|
> > 
> > Yields (before logging edited):  
> > “position”=\>“1”, “is\_menu”=\>“1”, “created\_at”=\>"2006-08-19
> > 
> > So where did my method disappear to?
> > 
> > Thanks in advance, Brittain
> 
> Can you show your caching code? How are you storing items in the  
> cache? Are you using marshal? Also if you run more then one mongrel  
> or fcgi how will you make sure that you always get the same cache  
> object to work with?

Thanks for the response Ezra. I’ve attached the cache below, they are  
simple hashes with object references. We’ve been using a couple others  
of similar design, this is the first we’ve ever added methods to the  
stored models.

We just discovered a short while ago when we started using  
mongrel\_cluster (which you appear already aware of) that we CANNOT get  
a handle to a specific cache. This is only an issue when we want to do  
a cache reload (happens infrequently), otherwise this data is truly  
static; however, if you’re a solution for that, we’d welcome hearing  
it.

Code below, edited for clarity:

===

require ‘singleton’

class MenuCache  
include Singleton

# Hash to hold settings

@@MENU\_HOME\_PAGE = nil  
@@MENUS = {} # Hash of all menus

def self.home\_page  
@@MENU\_HOME\_PAGE = @@MENU\_HOME\_PAGE ||  
get\_menu\_by\_key(Pref.get\_s(“THEME\_HOME\_PAGE”))  
end

protected  
def self.get\_menu\_by\_key(a\_key)  
load\_cache if @@MENUS.blank?

```
return @@MENUS[a_key]

```

end

# Load and cache table data

def self.load\_cache  
@@MENU\_HOME\_PAGE = nil

```
@@MENUS.clear

tags = Tag.find_menus()
tags.each {|t|
  # Store in the global hash
  @@MENUS[t.a_key] = t

  ...
}

```

end  
end

---

<div class="post-metadata">

**Author:** ![Brittain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/4491bb/32.png) [@Brittain](https://www.ruby-forum.com/u/Brittain)\
**Post date:** [August 21, 2006, 4:48am UTC](https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738/4 "2006-08-21T04:48:00Z")

</div>

Tried the restart many times without success. I’ll give the marshal  
solution a shot and post back.

We’re implementing BackgroundRB for a number of other features so I’ll  
make sure to use it to solve the in process problem.

In the meantime, if anyone else has any ideas, I’d welcome hearing  
them.

Thanks.

---

<div class="post-metadata">

**Author:** ![Brittain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/4491bb/32.png) [@Brittain](https://www.ruby-forum.com/u/Brittain)\
**Post date:** [August 21, 2006, 3:33am UTC](https://www.ruby-forum.com/t/method-missing-error-when-caching-an-activerecord-model/65738/5 "2006-08-21T03:33:53Z")

</div>

On Aug 20, 2006, at 5:04 PM, Brittain wrote:

> to do
> 
> end  
> @@MENU\_HOME\_PAGE = nil  
> end  
> end

```
Just to get the obvious out of the way, did you restart your

```

webserver after you made changes to the cached models? That could  
make this happen. Other then that I would think this should work  
fine. If you need to have a cache like this that gets updated during  
the app running you need to put it into its own process that all your  
rails backends can talk to. I have caching built into my backgroundrb  
plugin[1] that may be useful to you. But your solution should work as  
it is. If its still doesn’t work even after a server restart then  
perhaps you need to serialize the models before storage and  
unserialize them on the way out. Use Marshal.dump(obj) and  
Marshal.load(obj) for this.

Cheers-  
-Ezra

[1] [http://backgroundrb.rubyforge.org](http://backgroundrb.rubyforge.org)
