# Belongs\_to causing NoMethodError exceptions ...?

**URL:** <https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895>\
**Category:** Rails\
**Created:** [December 29, 2005, 10:31am UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895 "2005-12-29T10:31:31Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [December 29, 2005, 10:31am UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/1 "2005-12-29T10:31:31Z")

</div>

I’ve got a really strange problem using belongs\_to. I apologize in  
advance for the length… this is going to take a while to explain.

Basic idea: Creating a User requires that the user enter an email  
address and activation key that matches an existing PendingUser.  
After creating the user successfully, that pending user should be  
marked as “used”.

The problem:  
When I add a belongs\_to :pending\_user declaration to the User class,  
attempting to save a User yields this exception (taken here from the  
output of a simple test case – code below.) You’ll note some lines  
in the User class with two hashes ‘##’ preceding them – those are  
alternate statements that avoid using the .pending\_user attribute. If  
you comment out the belongs\_to :pending\_user and use the alternate  
statements (which just work with the pending\_user\_id field),  
everything seems to work fine.

1. Error:  
test\_create\_with\_valid\_pending\_user(UserTest):  
NoMethodError: undefined method `updated?' for #<PendingUser:0x8d09310> /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/base.rb:1498:in `method\_missing’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/  
active\_record/callbacks.rb:341:in `callback' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/callbacks.rb:335:in `callback’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/  
active\_record/callbacks.rb:330:in `each' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/callbacks.rb:330:in `callback’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/  
active\_record/callbacks.rb:248:in `create_or_update' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/base.rb:1226:in `save\_without\_validation’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/  
active\_record/validations.rb:698:in `save_without_transactions' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/transactions.rb:126:in `save’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/  
active\_record/transactions.rb:126:in `transaction' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/transactions.rb:91:in `transaction’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/  
active\_record/transactions.rb:118:in `transaction' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/transactions.rb:126:in `save’  
test/unit/user\_test.rb:62:in `test\_create\_with\_valid\_pending\_user’

I’m not calling the ‘updated?’ method anywhere in my code, but  
looking in ${PREFIX}/lib/ruby/gems/1.8/doc/activerecord-1.13.2/rdoc/  
classes/ActiveRecord/Associations/ClassMethods.src, it seems that  
belongs\_to calls the .updated? method.

Any light you can shed would be greatly appreciated – I’ve been  
banging my head against this for a few days, and no one on  
#rubyonrails on freenode has been able to figure out what’s going on.

-Marshall Pierce

Code follows…

Test case:

require File.dirname( **FILE** ) + ‘/…/test\_helper’

class UserTest \< Test::Unit::TestCase  
fixtures :accounts, :pending\_users

# we don’t need the users fixture – all we’re testing here is

creating a new user

# and the corresponding validation of the associated pending user

and account  
def setup  
@new = User.new  
# give it a valid email address  
@new.email\_address = pending\_users(:ok\_req).email\_address  
@new.password = @new.password\_confirmation = ‘doesntmatter’  
@new.activation\_key = ‘activationkey’  
@new.account\_id = pending\_users(:ok\_req).account\_id  
end

def test\_create\_with\_valid\_pending\_user  
assert @new.save  
end  
end

SQL definitions for the tables for the classes involved (postgresql):

DROP TABLE generic\_users CASCADE;  
CREATE TABLE generic\_users (  
password\_hash text NOT NULL  
, email\_address text UNIQUE NOT NULL  
, created\_at timestamp with time zone NOT NULL  
, updated\_at timestamp with time zone NOT NULL  
);

DROP TABLE users CASCADE;  
CREATE TABLE users (  
LIKE generic\_users INCLUDING DEFAULTS  
, id SERIAL PRIMARY KEY  
, account\_id int NOT NULL REFERENCES accounts(id) ON  
UPDATE CASCADE ON DELETE CASCADE  
, is\_account\_admin bool NOT NULL DEFAULT false  
, email\_validation\_key text NOT NULL  
, email\_validated bool NOT NULL DEFAULT false  
, pending\_user\_id int NOT NULL REFERENCES pending\_users(id)  
ON UPDATE CASCADE ON DELETE CASCADE  
);

DROP TABLE pending\_users CASCADE;  
CREATE TABLE pending\_users (  
id SERIAL PRIMARY KEY  
, account\_id int NOT NULL REFERENCES accounts(id) ON  
UPDATE CASCADE ON DELETE CASCADE  
, email\_address text UNIQUE NOT NULL  
, activation\_key\_hash text NOT NULL  
, created\_at timestamp with time zone NOT NULL  
, updated\_at timestamp with time zone NOT NULL  
, used bool NOT NULL DEFAULT false  
);

The class definitions: (yeah, I know – re-implementing login logic  
yet again is dumb, but this isn’t near completion yet, so don’t give  
me too much grief about it. 🙂

class GenericUser \< ActiveRecord::Base

validates\_presence\_of :password, :password\_confirmation, :email\_address  
validates\_uniqueness\_of :email\_address  
validates\_confirmation\_of :password

# password must be at least 8 characters long

validates\_format\_of :password, :with =\> %r{^.{8,}$}, :message =\>  
“must be at least 8 characters”

validates\_format\_of :email\_address, :with =\> MiscUtils::EMAIL\_REGEX

# user can only supply these params

attr\_accessible :password, :password\_confirmation, :email\_address

# class variable – see koz’s post [http://www.koziarski.net/](http://www.koziarski.net/)

archives/2005/07/16/environment  
cattr\_accessor :current\_user

# non-db variables

attr\_accessor :password

def before\_save  
#breakpoint(“generic user before\_save”)  
# save the new hash if the password is set  
# XXX - only set password\_hash during methods that can change  
password  
self.password\_hash = MiscUtils.hexdigest(@password) unless  
@password.nil?  
end

def after\_save  
@password = nil  
@password\_confirmation = nil  
end

def try\_to\_login  
self.class.lookup(self.email\_address, @password)  
end

# Class methods

def self.lookup(email\_address, password, additional\_conds = ‘’)  
hashed\_password = MiscUtils.hexdigest(password)  
begin  
find( :first,  
:conditions =\> [“email\_address = ? and password\_hash  
= ?” + additional\_conds,  
email\_address, hashed\_password])  
rescue  
return nil  
end  
end

end

* * *

class User \< GenericUser  
set\_table\_name “users”

belongs\_to :account  
belongs\_to :pending\_user

validates\_presence\_of :activation\_key

attr\_accessible :activation\_key

# non-db variable

attr\_accessor :activation\_key

# XXX: need to make sure that hypothetical user-editing tools

don’t allow malicious queries

# to change their account\_id or anything like that

def validate\_on\_create  
# we use an artificial, non db-backed parameter to hold the  
activation key,  
# then perform lookup here so we have access to errors.add, etc.  
@pending\_user = PendingUser.lookup(self.email\_address,  
@activation\_key)  
if @pending\_user.nil?  
errors.add\_to\_base(“Invalid email address or activation key”)  
return false;  
elsif @pending\_user.used == true  
# XXX : only for debug. TMI.  
errors.add\_to\_base(“User request already used”)  
end

```
 begin
   self.account = Account.find(@pending_user.account_id)
 rescue
   errors.add(:account_id, "is invalid")
 end

```

end

def before\_create  
self.email\_address = @pending\_user.email\_address  
self.account = @pending\_user.account

```
 ##self.pending_user = @pending_user
 self.pending_user_id = @pending_user.id

 # XXX: send an email with the activation key here...
 self.email_validation_key = MiscUtils.random_string(80)

 # XXX: since we're not sending email, manually set the

```

validation flag  
self.email\_validated = true  
#breakpoint(“user before\_create finish”)  
end

def after\_create  
# mark the pending user as used  
# XXX - handle failure better

```
 ##self.pending_user.used = true
 @pending_user.used = true

 ##unless self.pending_user.save
 unless @pending_user.save
   ##raise "couldn't save pending user #{self.pending_user.id}"
   raise "couldn't save pending user #{@pending_user.id}"
 end

```

end

def self.lookup(email\_address, password)  
super(email\_address, password, “and email\_validated = true”)  
end

end

* * *

class PendingUser \< ActiveRecord::Base  
validates\_presence\_of :email\_address, :account\_id  
validates\_uniqueness\_of :email\_address  
validates\_format\_of :email\_address, :with =\> MiscUtils::EMAIL\_REGEX

attr\_accessible :email\_address, :account\_id

attr :activation\_key

belongs\_to :account  
has\_one :user

# XXX: eventually we’ll want to programmatically set which account

the pending user will

# be tied to, and remove the accessible, etc symbols. (that is,

pull it from the current

# user’s info.)

def validate  
begin  
self.account = Account.find(self.account\_id)  
rescue  
errors.add(:account\_id)  
end  
end

# need to create an activation key and store its hash

def before\_create  
#randkey = MiscUtils.random\_string(20)  
# XXX: right now we’re not sending emails, so we won’t know what  
the un-hashed key was…  
randkey = “foo”  
self.activation\_key\_hash = MiscUtils.hexdigest(randkey)  
end

# simple wrapper to do the digest’ing of the key

def self.lookup(email\_address, key)  
hashed\_key = MiscUtils.hexdigest(key)  
begin  
find( :first,  
:conditions =\> [“email\_address = ? and  
activation\_key\_hash = ? and used = false”,  
email\_address, hashed\_key])  
rescue  
return nil  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [December 29, 2005, 1:44pm UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/2 "2005-12-29T13:44:29Z")

</div>

Marshall, try renaming before\_create in User to  
after\_validation\_on\_create  
to ensure the association is assigned before Rails tries to save it.  
Also rename before\_save in GenericUser to set\_password\_hash, and add  
“before\_save :set\_password\_hash” to ensure it’s also called.

–  
We develop, watch us RoR, in numbers too big to ignore.

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [December 29, 2005, 8:57pm UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/3 "2005-12-29T20:57:42Z")

</div>

On Dec 29, 2005, at 4:41, Mark Reginald J. wrote:

> Marshall, try renaming before\_create in User to  
> after\_validation\_on\_create  
> to ensure the association is assigned before Rails tries to save it.  
> Also rename before\_save in GenericUser to set\_password\_hash, and add  
> “before\_save :set\_password\_hash” to ensure it’s also called.
> 
> –  
> We develop, watch us RoR, in numbers too big to ignore.

Mark,  
Unfortunately, making those changes didn’t help any. Also, changing  
before\_create to after\_validation\_on\_create caused errors with using  
@pending\_user – after\_validation\_on\_create gets called even when  
validation failed, so sometimes @pending\_user was nil. So, I changed  
it to “set\_user\_attributes” and used before\_create :set\_user\_attributes,  
just in case that makes any difference. In any case, before\_create is,  
well, supposed to happen before the db interaction, so I don’t see why  
that would cause problems. It seems to me that the problem lies more  
with  
belongs\_to not mixing in the appropriate method to the PendingUser  
class.

Those changes don’t help, though – the test still fails in exactly the  
same way in exactly the same place.

-Marshall

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [December 30, 2005, 2:05am UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/4 "2005-12-30T02:05:24Z")

</div>

Marshall Pierce wrote:

> Those changes don’t help, though – the test still fails in exactly the  
> same way in exactly the same place.

OK, maybe it’s related to the AR sbuclassing you’re doing.

Or perhaps you can change the order of declarations. There’s  
this from [Peak Obsession](http://api.rubyonrails.com/classes/ActiveRecord/Callbacks.html)  
:

_IMPORTANT:_ In order for inheritance to work for the callback queues,  
you must specify the callbacks before specifying the associations.  
Otherwise, you might trigger the loading of a child before the parent  
has registered the callbacks and they won?t be inherited.

–  
We develop, watch us RoR, in numbers too big to ignore.

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [December 30, 2005, 2:56am UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/5 "2005-12-30T02:56:38Z")

</div>

On Dec 29, 2005, at 17:02, Mark Reginald J. wrote:

> Callbacks.html :
> 
> _IMPORTANT:_ In order for inheritance to work for the callback queues,  
> you must specify the callbacks before specifying the associations.  
> Otherwise, you might trigger the loading of a child before the parent  
> has registered the callbacks and they wonâ??t be inherited.

I re-ordered the top of the User class:  
class User \< GenericUser  
set\_table\_name “users”

before\_create :set\_user\_attributes

validates\_presence\_of :activation\_key

attr\_accessible :activation\_key

# non-db variable

attr\_accessor :activation\_key

belongs\_to :account  
#belongs\_to :pending\_user

Still no dice if I uncomment that belongs\_to. I can’t imagine what  
would fail just because I’m subclassing a subclass of AR, though…  
any idea where I should look?

-Marshall

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [January 2, 2006, 11:33am UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/6 "2006-01-02T11:33:25Z")

</div>

Marshall Pierce wrote:

> Still no dice if I uncomment that belongs\_to. I can’t imagine what  
> would fail just because I’m subclassing a subclass of AR, though… any  
> idea where I should look?

Did you find a solution to this Marshall?

–  
We develop, watch us RoR, in numbers too big to ignore.

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [May 9, 2006, 1:43pm UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/7 "2006-05-09T13:43:00Z")

</div>

I am having a similar problem, any updates?!?

---

<div class="post-metadata">

**Author:** ![Marshall\_Pierce](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@Marshall\_Pierce](https://www.ruby-forum.com/u/Marshall_Pierce)\
**Post date:** [May 10, 2006, 8:02pm UTC](https://www.ruby-forum.com/t/belongs-to-causing-nomethoderror-exceptions/225895/8 "2006-05-10T20:02:18Z")

</div>

I just experienced this error, and I was also using belongs\_to and a  
callback. Perhaps it was related to that. I banged my head against  
this all day today, with no change I could make to my code affecting  
the error.

Finally, I did a “rake tmp:clear”, restarted my development web server  
(in Locomotive) and shut down my browser to clear out any  
cache/sessions. The error magically disappeared, so you might want to  
try clearing out all your caches as well. Doing so has fixed similarly  
inexplicable errors for me in the past.

Come to think of it, I did re-order my associations and callbacks in  
the head of my model to put the callbacks first, as Mark suggested.  
Perhaps that was what actually fixed it, but I couldn’t see the change  
until doing a total refresh.

Good luck.

– Alison
