This project is archived and is in readonly mode.
delete in a relation doesn't call sweeper
Reported by Guillermo Álvarez | August 14th, 2008 @ 11:51 AM | in 2.x
Summary
- @users_friend.user.friends.delete(@users_friend.friend) # Dont call the sweeper observer
- @users_friend.destroy # Call the sweeper
- @users_friend.user.friends << @users_friend.friend # Call the sweeper
In these situation, destroy and destroy2 do similary things.
* One do: @users_friend.user.friends.delete(@users_friend.friend) *
And the other: @users_friend.destroy
Only the second one call the observer. I can understand these, and imagine why happens. But if these doesn't execute as expected, something like:
@users_friend.user.friends << @users_friend.friend
Must don't run too.
I put the important code here, and add a sample app as attachment.
class User < ActiveRecord::Base
has_many :users_friends
has_many :friends, :through => :users_friends
end
class UsersFriend < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
end
class UsersFriendSweeper < ActionController::Caching::Sweeper
observe UsersFriend
def after_destroy(record)
puts "after_destroy"
debugger
end
def before_destroy(record)
puts "before_destroy"
debugger
end
end
class UsersFriendsController < ApplicationController
cache_sweeper :users_friend_sweeper
...
# POST /users_friends
# POST /users_friends.xml
def create
@users_friend = UsersFriend.new(params[:users_friend])
@users_friend.user.friends << @users_friend.friend #These call the sweeper before_save
respond_to do |format|
flash[:notice] = 'UsersFriend was successfully created.'
format.html { redirect_to(@users_friend.user) }
format.xml { render :xml => @users_friend, :status => :created, :location => @users_friend }
format.js
end
end
def destroy
@users_friend = UsersFriend.find(params[:id])
@users_friend.user.friends.delete(@users_friend.friend) #Dont call the sweeper
respond_to do |format|
format.html { redirect_to(users_friends_url) }
format.xml { head :ok }
format.js { render :action => "create"}
end
end
def destroy2
@users_friend = UsersFriend.find(params[:id])
@users_friend.destroy #These call the sweeper before_destroy
respond_to do |format|
format.html { redirect_to(users_friends_url) }
format.xml { head :ok }
format.js { render :action => "create"}
end
end
...
end
Comments and changes to this ticket
-
legolin September 19th, 2008 @ 01:52 AM
- Tag changed from 2.1, activerecord to 2.1, activerecord
I'm having the same problem. The workaround is simple but it seems dangerous to have observers not listening to such things.
-
Pratik December 20th, 2008 @ 07:15 PM
- Assigned user set to Pratik
- State changed from new to incomplete
Could you please upload a patch/failing test - http://rails.lighthouseapp.com/p... ?
Thanks.
-
Ryan Bigg April 11th, 2010 @ 01:53 AM
- State changed from incomplete to stale
Please submit a patch if you wish to see this fixed.
-
Ryan Bigg April 11th, 2010 @ 02:03 AM
- State changed from stale to invalid
destroy sweepers should only work for destroys. The idea of using delete is that it runs like destroy, but without the callbacks. Use destroy rather than delete.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>