# Validation spanning multiple models(tables) - how can this be achieved in Rails?

**URL:** <https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546>\
**Category:** Rails\
**Created:** [January 13, 2009, 12:29am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546 "2009-01-13T00:29:24Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 13, 2009, 12:29am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/1 "2009-01-13T00:29:24Z")

</div>

Hi,

QUESTION: How can establishing validation that spans multiple models be  
achieved in Rails? That is in such a fashion that it is not possible  
for a  
developer to break the validation via using any of the public model  
methods  
(e.g. update\_attribute, save, create etc).

EXAMPLE:

- Concept: MAGAZINE can contain multiple ARTICLES, and an ARTICLE can be  
associated with multiple MAGAZINE (i.e. many to many). Cost of Magazine  
=  
Sum(Cost of Articles)
- Tables:  
(a) magazines (has “cost” field)  
(b) articles\_magazines (to map the many-to-many)  
(c) articles (has “total\_cost” field)

BUSINESS RULE to be implemented: Not possible for a database update  
that  
would end up with a Magazine’s “total\_cost” not being equal to the  
Sum(associated articles "cost"s)

ISSUES / QUESTIONS:  
(1) Assume would not try to implement rules at database constraint  
level???  
(2) Use of Model “before\_create” - but I’m assuming here if the Article  
is  
generated (Article.new), and then validation occurs, the code has NOT  
yet  
got to the bit where it updates the Magazine?  
(3) Use of “after\_create” - Add a check for both Magazine and Article  
perhaps here, noting the database record has been created by transaction  
NOT  
finalised yet. So would the following be the best way:

-----example-------  
class Magazine \< ActiveRecord::Base  
after\_save :business\_rule\_validation  
def business\_rule\_validation  
sum\_of\_articles = \<\< INSERT code that calculates SUM of Articles  
costs  
for all articles that are associated with the Magazine \>\>  
errors.add\_to\_base(“business rules fail”) if self.total\_cost !=  
sum\_of\_articles  
end  
end

class Article \< ActiveRecord::Base  
\<\< Add Same Concept as per Magazine \>\>  
end  
-----example-------

BUT wouldn’t this fail, as it assumes the Article create/update/delete  
and  
the Magazine create/update/delete is in the SAME transaction no???  
Does  
this mean you really have to create an overarching facade that handles  
creates/updates/deletes for Article/Magazines and somehow hide the  
normal  
per model save/update/delete???

–  
Greg  
[http://blog.gregnet.org/](http://blog.gregnet.org/)

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 13, 2009, 4:12am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/2 "2009-01-13T04:12:21Z")

</div>

On Tue, Jan 13, 2009 at 1:28 AM, Greg H. \<  
removed\_email\_address@domain.invalid\> wrote:

> Hi,
> 
> QUESTION: How can establishing validation that spans multiple models be  
> achieved in Rails? That is in such a fashion that it is not possible for a  
> developer to break the validation via using any of the public model methods  
> (e.g. update\_attribute, save, create etc).

A developer can always break validation with something like  
save\_with\_validation(false)

> EXAMPLE:
> 
> - Concept: MAGAZINE can contain multiple ARTICLES, and an ARTICLE can be  
> associated with multiple MAGAZINE (i.e. many to many). Cost of Magazine =  
> Sum(Cost of Articles)
> - Tables:  
> (a) magazines (has “cost” field)  
> (b) articles\_magazines (to map the many-to-many)  
> (c) articles (has “total\_cost” field)

Shouldn’t the magazine have the total\_cost field, and the article have a  
cost field?

> got to the bit where it updates the Magazine?  
> errors.add\_to\_base(“business rules fail”) if self.total\_cost !=  
> sum\_of\_articles  
> end  
> end

The after\_save callback is not for validation - see

> **[ActiveRecord::Callbacks](https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html)**
>
> Active Record Callbacks Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic before or after a change in the object state.

If you must validate use the validate method or and do your calculations  
and  
validation in there.

> per model save/update/delete???
> 
> –  
> Greg  
> [http://blog.gregnet.org/](http://blog.gregnet.org/)
> 
> >

Instead of storing the total cost and doing all this validation, I’d  
calculate the magazine total\_cost as needed  
class Magazine \< ActiveRecord::Base  
def total\_cost  
articles.to\_a.sum(&:cost)  
end  
end

–  
Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 13, 2009, 7:16am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/3 "2009-01-13T07:16:31Z")

</div>

yep - the magazine should have the total\_cost field (slip when I typed  
in  
the example). Also you’re last suggestion is good, but I was trying to  
construct an easy example where it highlighted the  
multiple-model-spanning  
validation brick wall I’m at. So with this in mind, and assuming I use  
the  
“validate” approach (c.f. after\_create hook), I still have the same  
question  
really? So an example of the issue is:

i) assuming there is a validation routine in both Magazine and Article  
to  
check business rules, that is:  
(a) for Magazine: Has to have an associated Article before successful  
validation &  
(b) for Article: Has to have an associated Magazine before succesful  
validation  
ii) issue is that if I create a Magazine, the validation is then hit and  
fails because I haven’t yet created the Article (i.e. so they don’t tie  
together)  
iii) if I create Article first to cover this then it fails because there  
isn’t a Magazine yet  
iv) I could put the creation in a method like  
“create\_magazine\_article\_pair”  
and remove these above-mentioned validation checks, however this  
wouldn’t  
then protect against use of base methods (e.g. create/update/delete  
would  
still be available as part of ActiveRecord)

Is there anyway out of this? i.e. to end up with a very solid  
data-access  
layer that doesn’t allow for the business rules to be broken?

thanks

On Tue, Jan 13, 2009 at 1:11 PM, Andrew T. \<  
removed\_email\_address@domain.invalid\> wrote:

> > - Tables:
> > 
> > (3) Use of “after\_create” - Add a check for both Magazine and Article  
> > sum\_of\_articles
> 
> ```
> class Magazine < ActiveRecord::Base
> 
> ```
> 
> “I have never let my schooling interfere with my education” - Mark Twain
> 
> >

–  
Greg  
[http://blog.gregnet.org/](http://blog.gregnet.org/)

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 13, 2009, 10:13am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/4 "2009-01-13T10:13:08Z")

</div>

On Tue, Jan 13, 2009 at 8:15 AM, Greg H. \<  
removed\_email\_address@domain.invalid\> wrote:

> validation &  
> create/update/delete would still be available as part of ActiveRecord)
> 
> > removed\_email\_address@domain.invalid\> wrote:  
> > save\_with\_validation(false)
> > 
> > > (b) articles\_magazines (to map the many-to-many)  
> > > would end up with a Magazine’s “total\_cost” not being equal to the  
> > > finalised yet. So would the following be the best way:  
> > > end  
> > > \<\< Add Same Concept as per Magazine \>\>  
> > > Greg  
> > > articles.to\_a.sum(&:cost)

Nice challenge, I’ve never had to do this (and am still not convinced of  
why  
you would need to - I would usually be happy with something like a  
magazine  
being created with no articles and then have the articles added later)  
but  
anyway, here’s a solution:

You (can’t) do it with the standard association helpers (that I can work  
out) but I solved it by creating an add\_article method that stores  
to-be-saved articles in an array and then checks both that array and the  
association on validation. Once the magazine is saved, it takes care of  
saving the articles which will validate because they have a magazine.

class Magazine \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :articles  
after\_save :save\_articles

def initialize(\*args)  
super(\*args)  
@article\_array = []  
end

def total\_cost  
articles.to\_a.sum(&:cost)  
end

def add\_article(article)  
@article\_array \<\< article  
end

private  
def validate  
errors.add(:title, “can’t have no articles”) if articles.size == 0  
&&  
@article\_array.size == 0  
end

def save\_articles  
@article\_array.each do |article|  
article.magazines \<\< self  
article.save!  
end  
end  
end

class Article \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :magazines

def validate  
errors.add(:title, “can’t have no magazines”) if magazines.size == 0  
end  
end

class MagazineTest \< ActiveSupport::TestCase  
test “magazine can’t be saved with no articles” do  
assert\_raise ActiveRecord::RecordInvalid do  
Magazine.create!(:title =\> ‘Test Magazine’)  
end  
end

test “magazine can be save with articles” do  
magazine = Magazine.new(:title =\> ‘Test Magazine’)  
article = Article.new(:title =\> ‘Test Article’, :cost =\> 20)  
magazine.add\_article article

```
assert_nothing_thrown do
  magazine.save!
end

assert !magazine.new_record?
assert !article.new_record?

```

end  
end

class ArticleTest \< ActiveSupport::TestCase  
test “article can’t be saved with no magazines” do  
assert\_raise ActiveRecord::RecordInvalid do  
Article.create!(:title =\> ‘Test Article’, :cost =\> 20)  
end  
end  
end

–  
Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 13, 2009, 1:24pm UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/5 "2009-01-13T13:24:41Z")

</div>

thanks for pondering this one with me Andrew - I’ll need to think about  
this  
tomorrow 🙂 , couple of off-the-cuff comments:

- very neat

- just wondering if this will work for multiple magazines linked to one  
article (i.e. many-to-many)

- do you think there’s no way to solve this without creating a new  
method in  
fact (like your “add\_article”)?

- one thing that this has made me realize is that I was also thinking  
of/assuming that my validation checks would be database based (e.g.  
search  
database to see result), but by working in the object world this helps  
remove the inherit database transaction/commits only approach where I  
was  
getting stuck seeing how to do it

regards  
Greg

On Tue, Jan 13, 2009 at 7:12 PM, Andrew T. \<  
removed\_email\_address@domain.invalid\> wrote:

> > i) assuming there is a validation routine in both Magazine and Article to  
> > iv) I could put the creation in a method like  
> > removed\_email\_address@domain.invalid\> wrote:
> > 
> > > > Sum(Cost of Articles)
> > > > 
> > > > got to the bit where it updates the Magazine?  
> > > > errors.add\_to\_base(“business rules fail”) if self.total\_cost !=
> > > 
> > > > per model save/update/delete???  
> > > > calculate the magazine total\_cost as needed
> 
> to-be-saved articles in an array and then checks both that array and the  
> end  
> def validate  
> end  
> test “magazine can’t be saved with no articles” do  
> assert\_nothing\_thrown do  
> assert\_raise ActiveRecord::RecordInvalid do  
> [http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)
> 
> “I have never let my schooling interfere with my education” - Mark Twain
> 
> >

–  
Greg  
[http://blog.gregnet.org/](http://blog.gregnet.org/)

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 15, 2009, 1:21am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/6 "2009-01-15T01:21:46Z")

</div>

I was thinking that one generic approach to handle cross model  
validations  
could be:

[1] VALIDATE AT OBJECT LEVEL: Validate your specific cross model rules  
at  
the Rails object level (i.e. before a “save” using the Rails validate)

- have a “model objects array” to add each associated model object that  
was  
part of the validation

[2] ENSURE ALL MODELS THAT WERE PART OF VALIDATION ARE SAVED: In each  
models  
“after\_save” then check it’s list of “model objects array” to ensure  
each is  
actually saved, then if not either save all, or if there is an issue  
then  
issue manual Rollback so that all items are rolled back.

Probem: I’m noting that re [1] and validating at the object level, if I  
allocate a book to a chapter, whilst the “chapter.book” works, the call  
“book\_object.chapters” does not work??? Any way around this or is this a  
rails thing? i.e. my concept was in the object world the links should  
have  
been in place. Example:  
b = Book.new  
c = Chapter.new  
c.book = b  
c.book ==\> works and gives b object  
b.chapters ==\> DOES NOT WORK - gives []

tks

On Tue, Jan 13, 2009 at 11:11 PM, Andrew T. \<  
removed\_email\_address@domain.invalid\> wrote:

> Thank you  
> You can do it though, you’ll just need to implement an add\_magazine method  
> to save a model at some point where the other isn’t saved and then the  
> magazine.articles \<\< Article.new(…)  
> abstraction of the models and you would need to couple more tightly to the  
> [http://ramblingsonrails.com](http://ramblingsonrails.com)  
> [http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)
> 
> “I have never let my schooling interfere with my education” - Mark Twain
> 
> >

–  
Greg  
[http://blog.gregnet.org/](http://blog.gregnet.org/)

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 13, 2009, 2:12pm UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/7 "2009-01-13T14:12:00Z")

</div>

Greg

On Tue, Jan 13, 2009 at 2:24 PM, Greg H. \<  
removed\_email\_address@domain.invalid\> wrote:

> thanks for pondering this one with me Andrew - I’ll need to think about  
> this tomorrow 🙂 , couple of off-the-cuff comments:
> 
> - very neat

Thank you

> - just wondering if this will work for multiple magazines linked to one  
> article (i.e. many-to-many)

It does but I only focussed on the magazine side as with the  
magazine/article relationship it’s more likely that you’ll create a  
magazine  
and add articles than create an article and add magazines.  
You can do it though, you’ll just need to implement an add\_magazine  
method  
to the article model  
The validations definitely work both ways, check the tests.

> - do you think there’s no way to solve this without creating a new method  
> in fact (like your “add\_article”)?

I played around with the various collection methods but each of them  
tries  
to save a model at some point where the other isn’t saved and then the  
validations will fail. Also most of the association methods rely on  
there  
being an id in the association model (i.e. it must be saved).  
My solution doesn’t require either model to be saved and handles the  
saving  
of children when needed.  
My solution will also continue to work after creation if you’re updating  
deleting children etc. E.g. You don’t have to use the add\_article method  
once you have at least one article saved with a link to the magazine.  
You could do:  
magazine.add\_article article  
magazine.save!  
magazine.articles \<\< Article.new(…)

> - one thing that this has made me realize is that I was also thinking  
> of/assuming that my validation checks would be database based (e.g. search  
> database to see result), but by working in the object world this helps  
> remove the inherit database transaction/commits only approach where I was  
> getting stuck seeing how to do it

You could deal with it more in the database but then you would lose the  
abstraction of the models and you would need to couple more tightly to  
the  
database.

> regards  
> Greg

–  
Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 15, 2009, 7:21am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/8 "2009-01-15T07:21:30Z")

</div>

On Thu, Jan 15, 2009 at 7:46 AM, Greg H. \<  
removed\_email\_address@domain.invalid\> wrote:

> # ----------- BOOK ---------------
> 
> end  
> @c.book = @b  
> @c.save!  
> @c.book = @b
> 
> ```
> @c = Chapter.new(:amount => 100)
> 
> ```
> 
> deleted" do  
> lambda{ @c.save! }.should raise\_error  
> @c.book = @b  
> $ ./script/autospec  
> Finished in 0.280484 seconds
> 
> 10 examples, 1 failure
> 
> * * *

Greg, put in a before\_delete callback to see if the deletion would leave  
the  
one side open and then return false if it would.

–  
Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 15, 2009, 6:47am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/9 "2009-01-15T06:47:01Z")

</div>

PS. Here’s an update where I’m at if anyone whats to comment. Not  
quite  
finished however I’m wondering now if I ensure solid validation level  
checks  
in model validations (e.g. both ends of an association are working,  
means  
have to set both ends manually) that I could then rely on Rails to  
actually  
save both ends of an association even if you only save one. (e.g. seems  
when  
I save book, chapter also gets saved, and vice-versa). Here’s where I’m  
at:

* * *

require File.expand\_path(File.dirname( **FILE** ) + ‘/…/spec\_helper’)

# ----------- BOOK ---------------

class Book \< ActiveRecord::Base  
has\_many :chapters

def validate  
if self.chapters.length == 0  
errors.add\_to\_base(“Book does not have an associated Chapter”)  
end  
end

end

# ----------- CHAPTER ---------------

class Chapter \< ActiveRecord::Base  
belongs\_to :book

def validate  
if !self.book  
errors.add\_to\_base(“Chapter does not have an associated Book”)  
end  
end

end

# --------- RSPEC (BOOK) ------------

describe Book do  
before(:each) do  
@valid\_attributes = {:amount =\> 100}  
@b = Book.new(:amount =\> 100)  
@c = Chapter.new(:amount =\> 100)  
end

it “should save without error when association is in place” do  
@c.book = @b  
@b.chapters = [@c]  
@b.save!  
@c.save!  
end

it “should delete without error when both ends of association are  
deleted”  
do  
@c.book = @b  
@b.chapters = [@c]  
@b.save!  
@c.save!

```
@c.destroy
@b.destroy

```

end

it “should fail for SAVE! if there is no association (OBJECT LEVEL)”  
do  
lambda{ @b.save! }.should raise\_error  
end

it “should fail for SAVE! if there is no association (DATABASE LEVEL)”  
do  
@c.book = @b  
@b.chapters = [@c]  
lambda{ @b.save! }.should\_not raise\_error #on basis that Rails will  
save Chapter automatically  
end

it “should fail for DELETE if one side left open” do  
@c.book = @b  
@b.chapters = [@c]  
@b.save!  
@c.save!

```
lambda{ @b.destroy }.should raise_error

```

end

end

# ----------RSPEC (CHAPTER) --------------------

describe Chapter do  
before(:each) do  
@valid\_attributes = {:amount =\> 100}  
@b = Book.new(:amount =\> 100)  
@c = Chapter.new(:amount =\> 100)  
end

it “should save without error when association is in place” do  
@c.book = @b  
@b.chapters = [@c]  
@b.save!  
@c.save!  
end

it “should delete without error when both ends of association are  
deleted”  
do  
@c.book = @b  
@b.chapters = [@c]  
@b.save!  
@c.save!

```
@c.destroy
@b.destroy

```

end

it “should fail for SAVE! if there is no association (OBJECT LEVEL)”  
do  
lambda{ @c.save! }.should raise\_error  
end

it “should fail for SAVE! if there is no association (DATABASE LEVEL)”  
do  
@c.book = @b  
@b.chapters = [@c]  
lambda{ @c.save! }.should\_not raise\_error # on basis that Rails  
will  
automatically save Book  
end

it “should fail for DELETE if one side left open” do  
@c.book = @b  
@b.chapters = [@c]  
@b.save!  
@c.save!

```
lambda{ @c.destroy }.should raise_error

```

end

## end

$ ./script/autospec  
loading autotest/rails\_rspec  
/opt/local/bin/ruby  
/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.12/bin/spec  
spec/models/all\_in\_one\_test\_spec.rb -O spec/spec.opts  
F…

1. 

‘Chapter should fail for DELETE if one side left open’ FAILED  
expected Exception but nothing was raised  
./spec/models/all\_in\_one\_test\_spec.rb:114:

Finished in 0.280484 seconds

10 examples, 1 failure

* * *

On Thu, Jan 15, 2009 at 10:21 AM, Greg H. \<  
removed\_email\_address@domain.invalid\> wrote:

> each is actually saved, then if not either save all, or if there is an issue  
> c.book ==\> works and gives b object
> 
> > On Tue, Jan 13, 2009 at 2:24 PM, Greg H. \<
> > 
> > > 
> > 
> > My solution doesn’t require either model to be saved and handles the
> > 
> > > - one thing that this has made me realize is that I was also thinking
> > 
> > “I have never let my schooling interfere with my education” - Mark Twain

–  
Greg  
[http://blog.gregnet.org/](http://blog.gregnet.org/)

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 15, 2009, 7:22am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/10 "2009-01-15T07:22:05Z")

</div>

On Thu, Jan 15, 2009 at 8:20 AM, Andrew T. \<  
removed\_email\_address@domain.invalid\> wrote:

> > * * *
> > 
> > end  
> > end  
> > end  
> > @c.book = @b  
> > end  
> > @c.book = @b  
> > describe Chapter do  
> > @c.save!  
> > @b.destroy  
> > lambda{ @c.save! }.should\_not raise\_error # on basis that Rails will  
> > end
> 
> Greg, put in a before\_delete callback to see if the deletion would leave  
> the one side open and then return false if it would.

Sorry, it’s before\_destroy

–  
Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 15, 2009, 7:51am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/11 "2009-01-15T07:51:56Z")

</div>

just wondering what I would put in:  
(a) before\_destroy - then proactively destroy the other associated  
object,  
BUT if those objects had a before\_destory this could become circular no?  
(b) after\_destroy - test to see if both ends were destroy, but if one  
end  
tests first prior to the other end being destroyed this would be an  
issue  
no?

On Thu, Jan 15, 2009 at 4:21 PM, Andrew T. \<  
removed\_email\_address@domain.invalid\> wrote:

> > > save both ends of an association even if you only save one. (e.g. seems when  
> > > if self.chapters.length == 0  
> > > def validate  
> > > @valid\_attributes = {:amount =\> 100}
> > > 
> > > end  
> > > end  
> > > @c.book = @b  
> > > @c.save!  
> > > do  
> > > @c.save!  
> > > /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.12/bin/spec  
> > > 10 examples, 1 failure
> 
> –  
> Andrew T.  
> [http://ramblingsonrails.com](http://ramblingsonrails.com)  
> [http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)
> 
> “I have never let my schooling interfere with my education” - Mark Twain
> 
> >

–  
Greg  
[http://blog.gregnet.org/](http://blog.gregnet.org/)

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 15, 2009, 9:19am UTC](https://www.ruby-forum.com/t/validation-spanning-multiple-models-tables-how-can-this-be-achieved-in-rails/157546/12 "2009-01-15T09:19:15Z")

</div>

On Thu, Jan 15, 2009 at 8:51 AM, Greg H. \<  
removed\_email\_address@domain.invalid\> wrote:

> > > 
> > 
> > Sorry, it’s before\_destroy

I wouldn’t try do a dependant destroy, I’d return false (to stop the  
destroy) or raise an error so that the destroy never happens.  
If you want to destroy with the dependant you are going to have to put a  
special case destroy on one side that will automatically destroy it’s  
association.

So the one will make sure it can’t be destroyed if it will break  
referential  
integrity, the other side will destroy it’s dependent along with itself.

–  
Andrew T.  
[http://ramblingsonrails.com](http://ramblingsonrails.com)  
[http://www.linkedin.com/in/andrewtimberlake](http://www.linkedin.com/in/andrewtimberlake)

“I have never let my schooling interfere with my education” - Mark Twain
