On Aug 20, 2009, at 11:58 PM, [email protected] wrote:
> Maybe I'm looking at this the wrong way and with that - hopefully
> someone can either suggest a simpler way or the right way.
>
> I have a Quote model - for all intents and purposes, just say it has
> one attribute :price.
>
> I want to be able to add the following self-referential attributes
> (which I *think* should be under a has_many, through)
>
> Quotes
> has_many requotes through... something
>
> When a quote is made it's attached to a specific job and locked. When
> a similar job comes in, I want to take the original quote, duplicate
> it and update it to match the specs of the new job; the old quote
> still intact and both having a knowledge of their "parent-child"
> relationship.
>
> I've looked at Ryan Bates latest railscast on self referential
> relationships but that doesn't seem to solve the whole problem.
>
> Say I have quote_id 3 which has been requoted 3 different times. I
> then go back and requote one of those, say quote #4.. (check the
> "hopefully understandable" chart below)
>
> quote#3
> =quote#4
> ==quote#7
> =quote#5
> =quote#6
>
> quote 3 has 3 children and its first child has a child.
>
> now say I delete quote 4... quote 7 doesn't know who its proverbial
> daddy is. and quote 3 doesn't know it has any grandchildren. in
> theory, i'd like 3&7 to link up when the link between them breaks.
>
> any takers on this one?


Well, it's true that #4 knows its original, but #3 only knows about  
the requotes by asking, in effect, "Hey, I'm #3. Which of you quotes  
are requotes from me?"

class Quote
   belongs_to :original, :class_name => 'Quote'
   has_many :requotes, :class_name => 'Quote', :foreign_key => :original

   def requoted?
     !self.original.nil?
   end

   def requote
     raise "Oops! Can't requote an unsaved Quote" if self.new_record?
     child = self.clone
     child.original = self.id
   end
end

three = Quote.new(:price => 1.00) {|q| q.id = 3 }
three.save
four = three.requote; four.save
five = three.requote; five.save
six  = three.requote;  six.save
seven = four.requote; seven.save

OK, now then, is four.destroy allowed? (meaning does the business  
thing exist in such a way that it is OK?)

You might want to have a before_destroy callback that prevents a quote  
from being removed if it has been requoted.

class Quote
   before_destroy :ensure_no_requotes  # placed earlier than the  
has_many

   protected
   def ensure_no_requotes
     self.requotes.empty?
   end
end

Alternatively, you could treat the chain of requotes as a linked-list  
and
self.requotes.each {|r|r.original = self.original; r.save}
in an after_destroy callback perhaps.

-Rob

Rob Biedenharn          http://agileconsultingllc.com
[email protected]



--~--~---------~--~----~------------~-------~--~----~
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 [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to