Child record becomes orphan


#1

Hi all,

I’ve got these company (has) contacts relational tables. I want to make
sure a
company can’t be deleted when it still has contacts. (because I can now,
which results in nil like errors when listing the contacts …
obviously)

Are there any helpers to do so, is Rails aware of this? Or do I need to
put in
a condition before destroying the company record in question myself?

def destroy_company

Haven’t figured out the syntax yet so don’t laugh about the line

below.
if Contact.find_all(params[:company_id]) == Company.find(params[:id])
<<<
flash[:notice] = ‘This company has contacts.’
redirect_to :action => ‘show_company’, :id => @company.id
else
Company.find(params[:id]).destroy
redirect_to :action => ‘list_companies’
end
end

Thanx Regards,

Gerard.


“Who cares if it doesn’t do anything? It was made with our new
Triple-Iso-Bifurcated-Krypton-Gate-MOS process …”

My $Grtz =~ Gerard;
~
:wq!


#2

Gerard wrote:

Hi all,

I’ve got these company (has) contacts relational tables. I want to make
sure a
company can’t be deleted when it still has contacts. (because I can now,
which results in nil like errors when listing the contacts …
obviously)

Are there any helpers to do so, is Rails aware of this? Or do I need to
put in
a condition before destroying the company record in question myself?

If you setup your associations within the model correctly, you will be
able to do:

if Company.find(params[:id]).contacts.size > 0
…Don’t delete quite yet…
end

However, you can also set the :dependent => true flag in the association
which will then delete associated contacts before deleting the company.

Jake


#3

On Sun, 2006-01-01 at 19:52 +0100, Gerard wrote:

Haven’t figured out the syntax yet so don’t laugh about the line below.

Gerard.

Do you intend to force the user to delete all contacts in a company
prior to deleting it? You can have AR destroy all the contacts when a
company is destroyed. See this blog entry:

http://rubyurl.com/bE4

-Robby


/**************************************************************

  • Robby R., Founder & Executive Director *
  • PLANET ARGON, LLC | www.planetargon.com *
  • Ruby on Rails Development, Consulting, and Hosting *
  • Portland, Oregon | p: 503.351.4730 | f: 815.642.4068 *
  • blog: www.robbyonrails.com | book: www.programmingrails.com *
    ***************************************************************/

#4

Robby,

Do you intend to force the user to delete all contacts in a company
prior to deleting it? You can have AR destroy all the contacts when a
Good question. Probably (for ease of use), notify the user and then
delete
them all.

company is destroyed. See this blog entry:

http://rubyurl.com/bE4

-Robby


$biz = http://www.gp-net.nl ;
$fun = http://www.mrmental.com ;
~
~
:wq!


#5

Jake,

It works, however I get a “Called id for nil” error (on the line with <<
behind it), when wanting to redirect to the company’s detail page. After
blocking it’s deletion. Any clue?

def destroy_company
if Company.find(params[:id]).contacts
flash[:notice] = ‘This company has contacts.’

#this one works
#redirect_to :action => ‘list_companies’

this one does not

  redirect_to :action => 'show_company', :id => @company.id	<<
else
  Company.find(params[:id]).destroy
  redirect_to :action => 'list_companies'
end

end

Thanx

Regards,

Gerard.

On Sunday 01 January 2006 20:00, Jake J. tried to type something
like:

put in
which will then delete associated contacts before deleting the company.

Jake


“Who cares if it doesn’t do anything? It was made with our new
Triple-Iso-Bifurcated-Krypton-Gate-MOS process …”

My $Grtz =~ Gerard;
~
:wq!


#6

Robby,

Looked at your site and coding work. Very impressive. After having
thought the
mather through. I concluded the ‘recursive’ removal can be very nasty as
well. If for instance you have a customer table (has) projects (has)
tasks
the result can be a lot more records removed then was the intention.

Any experience on what’s practical?

Thanx a lot.

regards,

Gerard.

On Sunday 01 January 2006 20:02, Robby R. tried to type something
like:

myself?
end
http://rubyurl.com/bE4

-Robby


“Who cares if it doesn’t do anything? It was made with our new
Triple-Iso-Bifurcated-Krypton-Gate-MOS process …”

My $Grtz =~ Gerard;
~
:wq!


#7

Jake,

Not to spam your mailbox but … Solved it and still don’t know why. The
line
below ‘##’ did the trick. But the company’s id is known (since that the
one
I’m attempting to delete) so why should I init another object?

Thanx again (and again) … :slight_smile:

def destroy_company
if Company.find(params[:id]).contacts
flash[:notice] = ‘This company has contacts.’

With this line it works

  @company = Company.find(params[:id])
  redirect_to :action => 'show_company', :id => @company.id
else
  Company.find(params[:id]).destroy
  redirect_to :action => 'list_companies'
end

end

Thanx

Regards,

Gerard.

On Sunday 01 January 2006 20:00, Jake J. tried to type something
like:

put in
which will then delete associated contacts before deleting the company.

Jake


“Who cares if it doesn’t do anything? It was made with our new
Triple-Iso-Bifurcated-Krypton-Gate-MOS process …”

My $Grtz =~ Gerard;
~
:wq!


#8

Jake,

I’ve got what I’m looking for.

It will be the if statement, then a user confirmation, the a recursive
removall.

Thanx a lot!

Regards,

Gerard.

On Sunday 01 January 2006 20:00, Jake J. tried to type something
like:

put in
which will then delete associated contacts before deleting the company.

Jake


“Who cares if it doesn’t do anything? It was made with our new
Triple-Iso-Bifurcated-Krypton-Gate-MOS process …”

My $Grtz =~ Gerard;
~
:wq!


#9

Gerard wrote:

def destroy_company
if Company.find(params[:id]).contacts

Here, you’re just grabbing “contacts” from the Company class.

  flash[:notice] = 'This company has contacts.'

With this line it works

  @company = Company.find(params[:id])

This is the first time you initialize the “@company” instance.

  redirect_to :action => 'show_company', :id => @company.id
else
  Company.find(params[:id]).destroy
  redirect_to :action => 'list_companies'
end

end

I’m still a bit hung-over from last night, so forgive if I’m not
answering the question correctly. :slight_smile:

Your method is similar to how I delete things, too. Check to see if
there are objects under that company and notify the user. If the user
confirms, I delete the company and dependent objects. (I don’t require
the user to delete all contacts first, though)

In your code above, you called Company.find(params[:id]) twice because
you never stored the instance. You could have done:

@company = Company.find(params[:id])
if company.contacts.size > 0
flash[:notice] = ‘This company has contacts.’
redirect_to :action => ‘show_company’, :id => @company.id
else
@company.destroy
redirect_to :action => ‘list_companies’
end

I don’t recall right now, but I think you have to test
company.contacts.size. Your test above just checks “if
company.contacts” which I think will always evaluate true even if there
are no contacts.

Jake


#10

Jake

replies inline

With this line it works

  @company = Company.find(params[:id])

This is the first time you initialize the “@company” instance.
Am I correct when I say that after a page rendering al instances are
gone (as
in removed from memory, or wherever)?

I’m still a bit hung-over from last night, so forgive if I’m not
answering the question correctly. :slight_smile:
I know the feeling, but id didn’t affect your answers so don’t worry …
:wink:

In your code above, you called Company.find(params[:id]) twice because
you never stored the instance. You could have done:
Interesting point (performance wise). Does that mean I also do two
queries to
the database?

I don’t recall right now, but I think you have to test
company.contacts.size. Your test above just checks “if
company.contacts” which I think will always evaluate true even if there
are no contacts.
Your brilliant, I figured that one out later, because a company without
contacts also alerted that it would have contacts.

Learned a lot. Thanx!

Regards,

Gerard.


“Who cares if it doesn’t do anything? It was made with our new
Triple-Iso-Bifurcated-Krypton-Gate-MOS process …”

My $Grtz =~ Gerard;
~
:wq!