Hi everyone,
I finally came up with a solution, a very simple solution to this
problem. I overrode the destroy action in the Users controller, as
such:
class UsersController < BaseController
def destroy
# before destroying the user, update the user_id for all of the
user's comments
@user.comments_as_author.update_all("user_id = 0",
"commentable_type = 'Program'")
unless @user.admin? || @user.featured_writer?
@user.destroy
flash[:notice] = :the_user_was_deleted.l
else
flash[:error] = :you_cant_delete_that_user.l
end
respond_to do |format|
format.html { redirect_to users_url }
end
end
end
Hope this helps someone else that needs the same behavior.
Steve Bobrowski
On Sep 20, 8:09 pm, steveb <[email protected]> wrote:
> Bruno,
>
> I actually did try that approach first before the one above, but found
> that there are transaction interaction problems. So, for example, if I
> use:
>
> class User < ActiveRecord::Base
> before_destroy :unlink_comments
>
> def unlink_comments
> comments_as_author.each do |comment|
> debugger
> if comment.commentable_type == 'Program'
> comment.user_id = nil
> comment.save
> end
> end
> end
> end
>
> I get:
>
> TypeError in UsersController#destroy
>
> can't modify frozen hash
>
> Using the ruby-debug, I get a little more info:
>
> if comment.commentable_type == 'Program'
> (rdb:1) p comment
> #<Comment id: 22313, title: "", created_at: "2010-09-20 23:55:57",
> commentable_id: 2, commentable_type: "Program", user_id: 16,
> recipient_id: nil, comment: "<p>tester comment</p>", author_name: nil,
> author_email: nil, author_url: nil, author_ip: "127.0.0.1",
> notify_by_email: true, rating: 1, helpful_percentage: #<BigDecimal:
> 7f6d6e099f60,'0.0',9(18)>>
> (rdb:1) next
> /home/sbobrows/apps/rr/app/models/user.rb:12
> if comment.commentable_type == 'Program'
> (rdb:1) next
> /home/sbobrows/apps/rr/app/models/user.rb:13
> comment.user_id = nil
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:139
> if transaction_open && !outside_transaction?
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:139
> if transaction_open && !outside_transaction?
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:140
> transaction_open = false
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:141
> decrement_open_transactions
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:142
> if open_transactions == 0
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:142
> if open_transactions == 0
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:143
> rollback_db_transaction
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:148
> raise unless database_transaction_rollback.is_a?
> (ActiveRecord::Rollback)
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:148
> raise unless database_transaction_rollback.is_a?
> (ActiveRecord::Rollback)
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:151
> @transaction_joinable = last_transaction_joinable
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:153
> if outside_transaction?
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:153
> if outside_transaction?
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:155
> elsif transaction_open
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/
> filters.rb:208
> method.after(controller)
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/
> rescue.rb:162
> rescue_action(exception)
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/flash.rb:
> 152
> if defined? @_flash
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:
> 534
> send_response
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:
> 536
> process_cleanup
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/response.rb:70
> @block = block
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/response.rb:72
> if [204, 304].include?(status.to_i)
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/response.rb:72
> if [204, 304].include?(status.to_i)
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/response.rb:76
> [status.to_i, header, self]
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/
> dispatcher.rb:95
> run_callbacks :after_dispatch, :enumerator => :reverse_each
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/query_cache.rb:36
> clear_query_cache
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/query_cache.rb:37
> @query_cache_enabled = old
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/connection_pool.rb:365
> unless env.key?("rack.test")
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/connection_pool.rb:365
> unless env.key?("rack.test")
> (rdb:1) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/connection_pool.rb:366
> ActiveRecord::Base.clear_active_connections!
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/
> string_coercion.rb:26
> [status, headers, UglyBody.new(body)]
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/head.rb:11
> if env["REQUEST_METHOD"] == "HEAD"
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/head.rb:11
> if env["REQUEST_METHOD"] == "HEAD"
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/head.rb:14
> [status, headers, body]
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:101
> session_data = env[ENV_SESSION_KEY]
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:102
> options = env[ENV_SESSION_OPTIONS_KEY]
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:104
> if !session_data.is_a?(AbstractStore::SessionHash) ||
> session_data.send(:loaded?) || options[:expire_after]
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:104
> if !session_data.is_a?(AbstractStore::SessionHash) ||
> session_data.send(:loaded?) || options[:expire_after]
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:105
> session_data.send(:load!) if session_data.is_a?
> (AbstractStore::SessionHash) && !session_data.send(:loaded?)
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:105
> session_data.send(:load!) if session_data.is_a?
> (AbstractStore::SessionHash) && !session_data.send(:loaded?)
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:106
> session_data = marshal(session_data.to_hash)
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:108
> raise CookieOverflow if session_data.size > MAX
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:108
> raise CookieOverflow if session_data.size > MAX
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:110
> cookie = Hash.new
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:111
> cookie[:value] = session_data
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:112
> unless options[:expire_after].nil?
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:112
> unless options[:expire_after].nil?
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:116
> cookie = build_cookie(@key, cookie.merge(options))
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:117
> unless headers[HTTP_SET_COOKIE].blank?
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:117
> unless headers[HTTP_SET_COOKIE].blank?
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:120
> headers[HTTP_SET_COOKIE] = cookie
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/session/
> cookie_store.rb:124
> [status, headers, body]
> (rdb:1) next
> /var/lib/gems/1.8/gems/rack-1.1.0/lib/rack/lock.rb:13
> env[FLAG] = old
> (rdb:1) next
> /var/lib/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/
> reloader.rb:47
> [status, headers, BodyWrapper.new(body, lock)]
> (rdb:1) next
> /var/lib/gems/1.8/gems/rails-2.3.8/lib/rails/rack/log_tailer.rb:18
> tail_log
> (rdb:1) next
>
> Anyway, this led me to some research that said to reload the target
> record, so here's the modified version:
>
> def unlink_comments
> comments_as_author.each do |comment|
> debugger
> comment.reload
> if comment.commentable_type == 'Program'
> comment.user_id = nil
> comment.save
> end
> end
> end
>
> But still no luck.
>
> if comment.commentable_type == 'Program'
> (rdb:26) p comment
> #<Comment id: 22313, title: "", created_at: "2010-09-20 23:55:57",
> commentable_id: 2, commentable_type: "Program", user_id: 16,
> recipient_id: nil, comment: "<p>tester comment</p>", author_name: nil,
> author_email: nil, author_url: nil, author_ip: "127.0.0.1",
> notify_by_email: true, rating: 1, helpful_percentage: #<BigDecimal:
> 7f6d6dc6fb38,'0.0',9(18)>>
> (rdb:26) next
> /var/lib/gems/1.8/gems/activerecord-2.3.8/lib/active_record/
> connection_adapters/abstract/database_statements.rb:139
> if transaction_open && !outside_transaction?
> (rdb:26) p ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups
"CommunityEngine" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/communityengine?hl=en.