Destroy, dependent and performance

Hi!
This is my first post in this forum. I’m learning RoR for two weeks and
I’m very interested about how to improve this framework.

I was testing one app I’m working in and I had some problems with
destroying.

The code is simple (and maybe wrong, as I said i’m just learning!). When
you destroy a league, you send a message to all the users associated to
this league.

def destroy
name = @league.name
participants = @league.participants
if @league.destroy
for participant in participants
@message = Message.new(:title => “blabla”,:text => “blabla”,
:receiver_id => participant.id, :user_id => @user.id)
@message.save(false)
end
flash[:notice] = “League ‘#{name}’ was deleted, you are a criminal!”
redirect_to route(’/leagues’)
else
flash[:error] = ‘Something went wrong creating this league!’
redirect_to route(’/leagues’)
end
end

class League < ActiveRecord::Base
has_many :invitations, :dependent => :destroy
has_many :participants,:through => :invitations,:source =>
:user,:conditions => “accepted == ‘t’”
end

First of all:
Leagues and invitations are dependent as you can see in the model. When
I destroy a League the SQL generated is this:
[DEBUG] Invitation Load SELECT * FROM invitations WHERE
(invitations.league_id = 1)
[DEBUG] Invitation Destroy DELETE FROM invitations WHERE “id” = 12e
[DEBUG] Invitation Destroy DELETE FROM invitations WHERE “id” = 15

If you have 100 invitations, you have to do 101 db calls?
I think it will be better to just make a
DELETE FROM invitations WHERE league_id = 1

Maybe i’m not using :dependent =>:destroy in the correct way…

The second problem i have is about creating messages. When i call to
league.destroy it deletes all invitations and then my participants
variable is empty. Do you know what can i do?

Thank’s in advance and sorry for my english! I’m trying to learn it as
well.

Have a closer look at the docs for has_many (http://
api.rubyonrails.org/classes/ActiveRecord/Associations/
ClassMethods.html#M001103). If you want to get rid of all the
invitations without reading them into memory you want to
use :dependent=>:delete_all. :destroy should be used if you need to
do additional work in each associated object (e.g., they have
dependents as well) as it instantiates each associated object and
invokes destroy on it. :delete_all just deletes them at the db-level
without instantiating.

My guess as to why your participants local variable is empty is that
the method you’re using simply creates an object that points to the
‘participants’ association proxy on @league (it looks like an array,
but it’s really a proxy object). To get an array that won’t disappear
when the invitations are destroy you could probably do this…

participants = @league.participants.find(:all)

or

participants = @league.participants.dup

On Feb 15, 11:43 am, Pau R. [email protected]

Thank’s man! It’s nice to have a place like this forum with people like
you.

I didn’t understood the :delete_all description in the docs but now i
undertand how it works.

The second tip works as well. Great!

Thank’s!

Congrats!

On Feb 17, 8:29 pm, Pau R. [email protected]