# Going round in circles trying to save a HABTM

**URL:** <https://www.ruby-forum.com/t/going-round-in-circles-trying-to-save-a-habtm/49723>\
**Category:** Rails\
**Created:** [December 8, 2005, 1:39am UTC](https://www.ruby-forum.com/t/going-round-in-circles-trying-to-save-a-habtm/49723 "2005-12-08T01:39:26Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![esloane](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e19b73/32.png) [@esloane](https://www.ruby-forum.com/u/esloane)\
**Post date:** [December 8, 2005, 1:39am UTC](https://www.ruby-forum.com/t/going-round-in-circles-trying-to-save-a-habtm/49723/1 "2005-12-08T01:39:26Z")

</div>

G’Day Peter,  
Thanks again for your offer of help and once again my apologies for the  
prickly response(a result of hair-tearing frustration only).

My problem, really, is grasping the concept of how it all hangs  
together, rather than a specific technical issue. So I’m just coming at  
it one step at a time. My background is a long association with database  
and client server going way back to the functional programming days - so  
I can be a bit brick-headed with this stuff.

OK, here goes;  
Ruby version: 1.8.2 Rails 0.14.3

I’m concentrating on 3 tables here but the same kind of relationships  
occur throughout the database (currently 26 tables).  
CREATE TABLE `addresses` (  
`id` int(10) unsigned NOT NULL auto\_increment,  
`address_1` varchar(45) collate latin1\_general\_ci default NULL,  
`address_2` varchar(45) collate latin1\_general\_ci default NULL,  
`suburb` varchar(45) collate latin1\_general\_ci default NULL,  
`state` varchar(5) collate latin1\_general\_ci default NULL,  
`country` varchar(45) collate latin1\_general\_ci default NULL,  
PRIMARY KEY (`id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1\_general\_ci  
AUTO\_INCREMENT=21 ;

CREATE TABLE `jobs` (  
`id` int(10) unsigned NOT NULL auto\_increment,  
`job_types_fkid` int(10) unsigned NOT NULL default ‘0’,  
`job_number` varchar(10) collate latin1\_general\_ci default NULL,  
`job_type_id` int(10) unsigned default NULL,  
`address_id` int(10) unsigned default NULL,  
`job_phase_id` int(10) unsigned default NULL,  
`current_action_id` int(11) NOT NULL default ‘0’,  
`closed` tinyint(1) default NULL,  
PRIMARY KEY (`id`,`job_types_fkid`),  
KEY `Jobs_FKIndex1` (`job_types_fkid`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1\_general\_ci  
AUTO\_INCREMENT=3 ;

CREATE TABLE `jobs_addresses` (  
`job_id` int(10) unsigned NOT NULL default ‘0’,  
`address_id` int(10) unsigned NOT NULL default ‘0’,  
PRIMARY KEY (`job_id`,`address_id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1\_general\_ci;

Models:  
job.rb  
class Job \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :people  
has\_many :milestones  
has\_many :job\_phases ##Note: tables named singular\_plural are  
NOT link tables but lookups i.e contain a description of a code  
has\_many :people  
has\_and\_belongs\_to\_many :addresses, :join\_table =\> “jobs\_addresses”  
has\_many :reminders  
has\_many :discussions  
has\_many :actions  
has\_one :jobtype  
has\_many :documents  
has\_and\_belongs\_to\_many :organisations  
validates\_associated :address

end

address.rb  
class Address \< ActiveRecord::Base  
has\_one :address\_type  
has\_and\_belongs\_to\_many :jobs, :join\_table =\> “jobs\_addresses”  
has\_one :organisation  
has\_many :people  
end

I do actually have a job\_address model  
class JobAddress \< ActiveRecord::Base  
belongs\_to :jobs  
belongs\_to :addresses  
end  
Though I’m not at all sure of the impact of that.

In the job\_controller.rb I have  
def new  
@job = Job.new  
@address = Address.new  
end  
And  
def create  
@job = Job.new(params[:job])  
@address = Address.new(params[:address])  
if @job.save & @address.save \<= Line 54  
flash[:notice] = ‘Job was successfully created.’  
redirect\_to :action =\> ‘list’  
else  
render :action =\> ‘new’  
end  
end  
(This version of create is just one of many that I’ve tried - but I’ll  
stick with it to avoid confusion)

Running this I get;

NoMethodError in Job#create

undefined method `address’ for #Job:0x39d1ed8

RAILS\_ROOT: ./script/…/config/…  
Application Trace | Framework Trace | Full Trace

d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/base.rb:1497:in  
`method_missing' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/validations.rb:292:in`send’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/validations.rb:292:in  
`validates_each' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/validations.rb:291:in`each’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/validations.rb:291:in  
`validates_each' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/validations.rb:288:in`call’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/validations.rb:758:in  
`run_validations' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/validations.rb:752:in`each’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/validations.rb:752:in  
`run_validations' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/validations.rb:716:in`valid\_without\_callbacks’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/callbacks.rb:306:in  
`valid?' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/validations.rb:686:in`save\_without\_transactions’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/transactions.rb:126:in  
`save' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/transactions.rb:126:in`transaction’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/transactions.rb:91:in  
`transaction' d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active_record/transactions.rb:118:in`transaction’  
d:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.13.0/lib/active\_record/transactions.rb:126:in  
`save' #{RAILS_ROOT}/app/controllers/job_controller.rb:54:in`create’

Line 54 is “if @job.save & @address.save” and it is definitely @job.save  
that throws the exception. Interestingly, in other iterations  
@address.save works - @job.save still complains

Request

Parameters: {“commit”=\>“Save Job Data”, “job”=\>{“job\_number”=\>“G23”,  
“closed”=\>“false”, “job\_phase\_id”=\>“1”, “job\_type\_id”=\>“1”},  
“address”=\>{“country”=\>“Orstraya”, “suburb”=\>“Emerald”,  
“address\_1”=\>“Level 42”, “address\_2”=\>“77, Sunset Strip”,  
“state”=\>“Vic”}}

So what is driving me nuts is how to code this relationship to update  
the two main tables and the jobs\_addresses link table.

On another topic I’m also confused about push\_with\_attributes and why it  
does not appear to be a valid method within @job

> > @job.methods.sort  
> > =\> ["==", “===”, “=~”, “[]”, “[]=”, “ **id** ”, “ **send** ”, “`”,  
> > “action\_ids=”, “actions”, “actions=”, “actions\_count”, “add\_actions”,  
> > “add\_addresses”, “add\_discussions”, “add\_documents”, “add\_job\_phases”,  
> > “add\_milestones”, “add\_organisations”, “add\_people”, “add\_reminders”,  
> > “address\_ids=”, “addresses”, “addresses=”, “addresses\_count”,  
> > “after\_create”, “after\_destroy”, “after\_save”, “after\_update”, "  
> > after\_validation",“after\_validation\_on\_create”,“after\_validation\_on\_update”,  
> > “allow\_concurrency”, “allow\_concurrency=”, “attribute\_names”,  
> > “attribute\_present?”, “attributes”, “attributes=”,  
> > “attributes\_before\_type\_cast”, “b64encode”, “before\_create”,  
> > “before\_destroy”, “before\_save”, “before\_update”, “before\_validation”,  
> > “before\_validation\_on\_create”, “before\_validation\_on\_update”, “blank?”,  
> > “build\_jobtype”, “build\_to\_actions”, “build\_to\_discussions”,  
> > “build\_to\_documents”, “build\_to\_job\_phases”, “build\_to\_milestones”,  
> > “build\_to\_people”, “build\_to\_reminders”, “call\_allow\_concurrency”,  
> > “call\_colorize\_logging”, “call\_configurations”,“call\_default\_timezone”,  
> > “call\_generate\_read\_methods”, “call\_lock\_optimistically”, “call\_logger”,  
> > “call\_pluralize\_table\_names”, “call\_primary\_key\_prefix\_type”,  
> > “call\_record\_timestamps”, “call\_schema\_format”,“call\_table\_name\_prefix”,  
> > “call\_table\_name\_suffix”, “class”, “clear\_association\_cache”, “clone”,  
> > “colorize\_logging”, “colorize\_logging=”, “column\_for\_attribute”,  
> > “configurations”, “configurations=”, “connection”, “create”,  
> > “create\_in\_actions”, “create\_in\_discussions”, “create\_in\_documents”,  
> > “create\_in\_job\_phases”, “create\_in\_milestones”, “create\_in\_people”,  
> > “create\_in\_reminders”, “create\_jobtype”, “create\_or\_update”, “create\_or\_  
> > update\_with\_callbacks”,“create\_with\_callbacks”,“create\_with\_timestamps”,  
> > “create\_without\_timestamps”, “decode64”, “decode\_b”, “decrement”,  
> > “decrement!”, “default\_timezone”, “default\_timezone=”, “destroy”,  
> > “destroy\_with\_callbacks”, “destroy\_with\_transactions”,  
> > “destroy\_without\_callbacks”, "destroy\_without\_transactions  
> > ", “discussion\_ids=”, “discussions”, “discussions=”,  
> > “discussions\_count”, “display”, “document\_ids=”, “documents”,  
> > “documents=”, “documents\_count”, “dup”, “encode64”, “eql?”, “equal?”,  
> > “errors”, “extend”, “find\_all\_in\_actions”, “find\_all\_in\_discussions”,  
> > “find\_all\_in\_documents”, “find\_all\_in\_job\_phases”,  
> > “find\_all\_in\_milestones”, “find\_all\_in\_people”, “find\_all\_in\_reminders”,  
> > “find\_in\_actions”, “find\_in\_discussions”, “find\_in\_documents”,  
> > “find\_in\_job\_phases”, “find\_in\_milestones”, “find\_in\_people”,  
> > “find\_in\_reminders”, “freeze”, “frozen?”, “generate\_read\_methods”,  
> > “generate\_read\_methods=”, “has\_actions?”, “has\_addresses?”,  
> > “has\_attribute?”, “has\_discussions?”, “has\_documents?”,  
> > “has\_job\_phases?”, “has\_jobtype?”, “has\_milestones?”,  
> > “has\_organisations?”, “has\_people?”, “has\_reminders?”, “hash”, “id”,  
> > “id=”, “id\_before\_type\_cast”, “increment”, “increment!”, “initialize”,  
> > “initialize\_with\_callbacks”, “inspect”,  
> > “instance\_eval”,“instance\_of?”, “instance\_variable\_get”,  
> > “instance\_variable\_set”, “instance\_variables”, “is\_a?”,  
> > “is\_complex\_yaml?”, “job\_phase\_ids=”, “job\_phases”, “job\_phases=”,  
> > “job\_phases\_count”, “jobtype”, “jobtype=”, “jobtype?”, “kind\_of?”,  
> > “load”, “lock\_optimistically”,“lock\_optimistically=”,  
> > “locking\_enabled?”, “logger”, “logger=”, “method”, “methods”,  
> > “milestone\_ids=”, “milestones”, “milestones=”, “milestones\_count”,  
> > “new\_record?”, “nil?”, “object\_id”, “organisation\_ids=”,  
> > “organisations”, “organisations=”, “organisations\_count”, “people”,  
> > “people=”, “people\_count”, “person\_ids=”,“pluralize\_table\_names”,  
> > “pluralize\_table\_names=”, “primary\_key\_prefix\_type”,  
> > “primary\_key\_prefix\_type=”, “private\_methods”, “protected\_methods”,  
> > “public\_methods”, “quoted\_id”, “readonly!”, “readonly?”,  
> > “record\_timestamps”, “record\_timestamps=”, “reload”, “reminder\_ids=”,  
> > “reminders”, “reminders=”, “reminders\_count”, “remove\_actions”,  
> > “remove\_addresses”, “remove\_discussions”, “remove\_documents”,  
> > “remove\_job\_phases”, “remove\_milestones”, “remove\_organisations”,  
> > “remove\_people”, “remove\_reminders”, “remove\_subclasses\_of”, “require”,  
> > “require\_gem”, “require\_gem\_with\_options”, “require\_library\_or\_gem”,  
> > “respond\_to?”, “respond\_to\_without\_attributes?”, “returning”, “save”,  
> > “save!”, “save\_with\_transactions”, “save\_with\_validation”,  
> > “save\_without\_transactions”, “save\_without\_validation”, “schema\_format”,  
> > “schema\_format=”, “send”, “set\_jobtype\_target”, “silence\_stderr”,  
> > “silence\_warnings”, “singleton\_methods”, “subclasses\_of”, “suppress”,  
> > “table\_name\_prefix”, “table\_name\_prefix=”, “table\_name\_suffix”,  
> > “table\_name\_suffix=”, “taint”, “tainted?”, “to\_a”, “to\_param”, “to\_s”,  
> > “to\_yaml”, “to\_yaml\_properties”, “to\_yaml\_type”, “toggle”, “toggle!”,  
> > “transaction”, “type”, “untaint”, “update”, “update\_attribute”,  
> > “update\_attribute\_with\_validation\_skipping”,  
> > “update\_attribute\_without\_validation\_skipping”, “update\_attributes”,  
> > “update\_with\_callbacks”, “update\_with\_lock”, “update\_with\_timestamps”,  
> > “update\_without\_callbacks”, “update\_without\_timestamps”, “valid?”,  
> > “valid\_with\_callbacks”, “valid\_without\_callbacks”, “validate”,  
> > “validate\_associated\_records\_for\_actions”,  
> > “validate\_associated\_records\_for\_addresses”,  
> > “validate\_associated\_records\_for\_discussions”,  
> > “validate\_associated\_records\_for\_documents”,  
> > “validate\_associated\_records\_for\_job\_phases”,  
> > “validate\_associated\_records\_for\_milestones”,  
> > “validate\_associated\_records\_for\_organisations”,  
> > “validate\_associated\_records\_for\_people”,  
> > “validate\_associated\_records\_for\_reminders”, “validate\_on\_create”,  
> > “validate\_on\_update”]

OK - thats a lotta info for a daft wee problem - sorry if I’m inundating  
you;~)

Kind Regards,  
Eric.

---

<div class="post-metadata">

**Author:** ![esloane](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e19b73/32.png) [@esloane](https://www.ruby-forum.com/u/esloane)\
**Post date:** [December 8, 2005, 1:51am UTC](https://www.ruby-forum.com/t/going-round-in-circles-trying-to-save-a-habtm/49723/2 "2005-12-08T01:51:38Z")

</div>

Try something like this…

@job = Job.new(params[:job])  
@job.addresses \<\< Address.new(params[:address])  
if @job.save  
…

---

<div class="post-metadata">

**Author:** ![esloane](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e19b73/32.png) [@esloane](https://www.ruby-forum.com/u/esloane)\
**Post date:** [December 8, 2005, 2:40am UTC](https://www.ruby-forum.com/t/going-round-in-circles-trying-to-save-a-habtm/49723/3 "2005-12-08T02:40:11Z")

</div>

Hi,

On 12/8/05, Eric S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks again for your offer of help and once again my apologies for the  
> prickly response(a result of hair-tearing frustration only).

We have all been there! I think I may have a better idea of what may  
cause the error now … or maybe not 😉

Your jobs table has a address\_id column but your model does not use the  
“belongs\_to :address” macro but it does declare a validation on this  
field via  
“validates\_associated :address”. This validation will thus fail and  
cause that  
error.

See if removing “validates\_associated :address” or adding “belongs\_to  
:address”  
fixes the problem. If not then we will need to look closer.

BTW I would kill JobAddress - I am not sure if it hurts but you don’t  
need it.

Hope that helps.

–  
Cheers,

Peter D.

Blog: [http://www.RealityForge.org](http://www.RealityForge.org)
