# Validation performed on has\_many associations before updatin

**URL:** <https://www.ruby-forum.com/t/validation-performed-on-has-many-associations-before-updatin/109315>\
**Category:** Rails\
**Created:** [July 13, 2007, 11:36am UTC](https://www.ruby-forum.com/t/validation-performed-on-has-many-associations-before-updatin/109315 "2007-07-13T11:36:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [July 13, 2007, 11:36am UTC](https://www.ruby-forum.com/t/validation-performed-on-has-many-associations-before-updatin/109315/1 "2007-07-13T11:36:50Z")

</div>

Hi,

I have a Campaign model which has\_many :condition\_sets. The ConditionSet  
belongs\_to :campaign and also validates\_presence\_of :campaign\_id

Now, If I…

> > c = Campaign.new  
> > s = c.condition\_sets.build  
> > c.save!  
> > ActiveRecord::RecordInvalid: Validation failed: Condition sets is  
> > invalid
> 
> > s.errors.full\_messages  
> > =\> [“Campaign can’t be blank”]

I’d expect Rails to set the campaign\_id foreign key _before_ performing  
validation on the ConditionSet, right?

Removing the validates\_presence\_of :campaign\_id lets the campaign save…

> > c = Campaign.new  
> > s = c.condition\_sets.build  
> > c.save!  
> > s.campaign  
> > =\> #\<Campaign id: 1, created\_at: “2007-07-13 09:20:08”, updated\_at:  
> > “2007-07-13 09:20:08”\>

Am I just being dumb???

=========

Ruby version 1.8.6 (i686-darwin8.10.1)  
RubyGems version 0.9.4  
Rails version 1.2.3  
Active Record version 1.15.3  
Action Pack version 1.13.3  
Action Web Service version 1.2.3  
Action Mailer version 1.3.3  
Active Support version 1.4.2  
Edge Rails revision 436  
Application root /Users/ian/Projects/systino/trunk  
Environment development  
Database adapter mysql  
Database schema version 64

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [July 13, 2007, 12:15pm UTC](https://www.ruby-forum.com/t/validation-performed-on-has-many-associations-before-updatin/109315/2 "2007-07-13T12:15:04Z")

</div>

Ian L. wrote:

> =\> [“Campaign can’t be blank”]
> 
> I’d expect Rails to set the campaign\_id foreign key _before_ performing  
> validation on the ConditionSet, right?

campaign\_id can’t be set before it’s validated because it is unknown  
until the campaign is saved, and validation is designed to prevent  
anything being saved unless the whole object hierarchy is valid.

The usual solution is:

```
class ConditionSet
  validates_presence_of :campaign # Checks for valid object or fk
end
c = Campaign.new
s = c.condition_sets.build
s.campaign = c # Currently not set automatically by Rails
c.save!

```

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

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [July 13, 2007, 4:51pm UTC](https://www.ruby-forum.com/t/validation-performed-on-has-many-associations-before-updatin/109315/3 "2007-07-13T16:51:49Z")

</div>

Thanks Mark, it seems pretty obvious now you’ve pointed it out.

I’m having a similar problem with a has\_one association this time but  
applying what I’ve learned here doesn’t seem to work. To confuse me even  
more, the parent has\_one association works fine.

Here is some debug of what my app is doing…

# BUILD Incentive::ConditionSet#build\_promoter ASSIGN Incentive::ConditionSet#promoter \<= Incentive::PromoterCondition ASSIGN FOREIGN Incentive::PromoterCondition#condition\_set \<= Incentive::ConditionSet

# BUILD Incentive::PromoterCondition#build\_order ASSIGN Incentive::PromoterCondition#order \<= Incentive::OrderCondition ASSIGN CONDITIONABLE FOREIGN Incentive::OrderCondition#order\_conditionable \<= Incentive::PromoterCondition

BUILD Incentive::OrderCondition#build\_order\_value  
ASSIGN Incentive::OrderCondition#order\_value \<=  
Incentive::OrderValueCondition  
ASSIGN FOREIGN Incentive::OrderValueCondition#order \<=  
Incentive::OrderCondition

ConditionSet, PromoterCondition and OrderCondition all save correctly,  
however OrderValueCondition fails due to order\_id being NULL. The  
situation  
is the same if I rely on the build\_\* methods.

So to recap… Campaign has\_many ConditionSets has\_one PromoterCondition  
has\_one OrderCondition has\_one OrderValueCondition. The only difference  
between the PromoterCondition / OrderCondition and OrderCondition /  
OrderValueCondition associations is that the PromoterCondition /  
OrderCondition is infact a polymorphic one via a OrderConditionable  
interface, but surely that shouldn’t be causing the problem?

Today really is a has\_many :headaches day!

Cheers  
Ian

---

<div class="post-metadata">

**Author:** ![elliterate](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/9de053/32.png) [@elliterate](https://www.ruby-forum.com/u/elliterate)\
**Post date:** [July 13, 2007, 6:32pm UTC](https://www.ruby-forum.com/t/validation-performed-on-has-many-associations-before-updatin/109315/4 "2007-07-13T18:32:04Z")

</div>

OK this is odd… or just not what I’m expecting.

class OrderValueCondition  
belongs\_to :order, :class\_name =\> ‘Incentive::OrderCondition’  
end

Rails should infer order\_id as the foreign key, right? I’m not sure what  
Rail thinks it is, because when I explicitly specify :foreign\_key =\>  
:order\_id it saves.

…the penny drops…

Just noticed:

DEPRECATION WARNING: The inferred foreign\_key name will change in  
Rails 2.0to use the association name instead of its class name when  
they differ.  
When using :class\_name in belongs\_to, use the :foreign\_key option to  
explicitly set the key name to avoid problems in the transition. See  
[Ruby on Rails — A web-app framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.](http://www.rubyonrails.org/deprecation) for details.

Doh!
