Forum: Ruby on Rails Child record becomes orphan

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
4710a8ada2adc162aaee4288d9879d8e?d=identicon&s=25 Gerard (Guest)
on 2006-01-01 19:54
(Received via mailing list)
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!
E51c6ae07e72cf04ef869868cb8eca6e?d=identicon&s=25 Jake Janovetz (Guest)
on 2006-01-01 20:00
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
B84d42a3a5c343f8fc6ab7d7f47fd3f5?d=identicon&s=25 Robby Russell (Guest)
on 2006-01-01 20:03
(Received via mailing list)
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 Russell, 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 *
***************************************************************/
588b32371b62ebe36d70fa712a1173f0?d=identicon&s=25 Gerard J. Petersen (Guest)
on 2006-01-01 21:22
(Received via mailing list)
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!
4710a8ada2adc162aaee4288d9879d8e?d=identicon&s=25 Gerard (Guest)
on 2006-01-01 21:25
(Received via mailing list)
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 Janovetz 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!
4710a8ada2adc162aaee4288d9879d8e?d=identicon&s=25 Gerard (Guest)
on 2006-01-01 22:22
(Received via mailing list)
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 Janovetz 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!
4710a8ada2adc162aaee4288d9879d8e?d=identicon&s=25 Gerard (Guest)
on 2006-01-01 22:28
(Received via mailing list)
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 Russell 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!
4710a8ada2adc162aaee4288d9879d8e?d=identicon&s=25 Gerard (Guest)
on 2006-01-01 22:37
(Received via mailing list)
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) .. :-)

 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 Janovetz 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!
E51c6ae07e72cf04ef869868cb8eca6e?d=identicon&s=25 Jake Janovetz (Guest)
on 2006-01-01 23:46
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. :)

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
4710a8ada2adc162aaee4288d9879d8e?d=identicon&s=25 Gerard (Guest)
on 2006-01-02 10:45
(Received via mailing list)
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. :)
I know the feeling, but id didn't affect your answers so don't worry ..
;-)

> 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!
This topic is locked and can not be replied to.