Ian Leitch
2007-Jul-13 09:36 UTC
Validation performed on has_many associations before updating the belongs_to foreign key?
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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Jul-13 10:13 UTC
Re: Validation performed on has_many associations before updating the belongs_to foreign key?
Ian Leitch wrote:> 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?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. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Ian Leitch
2007-Jul-13 14:50 UTC
Re: Validation performed on has_many associations before updating the belongs_to foreign key?
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 On 13/07/07, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> > > Ian Leitch wrote: > > > 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? > > 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. > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Ian Leitch
2007-Jul-13 16:30 UTC
Re: Validation performed on has_many associations before updating the belongs_to foreign key?
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 http://www.rubyonrails.org/deprecation for details. Doh! On 13/07/07, Ian Leitch <port001-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > 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 > > On 13/07/07, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org > wrote: > > > > > > Ian Leitch wrote: > > > > > 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? > > > > 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. > > > > > > > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---