开发者

Rails Observer, How to determine what Triggered the after_destroy

开发者 https://www.devze.com 2023-02-10 20:02 出处:网络
I have a observer setup as follows: class FeedObserver < ActiveRecord::Observer observe :permission def after_destroy(record)

I have a observer setup as follows:

class FeedObserver < ActiveRecord::Observer
  observe :permission
  def after_destroy(record)

    Rails.logger.info 'XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX'
    Rails.logger.info record.inspect
    Rails.logger.info record.class.name
    Ra开发者_如何学运维ils.logger.info record.class
    Rails.logger.info 'XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX'

  end

end

In the logs this ends up looking a little like:

XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX
#<Permission id: 52, project_id: 12, role_id: 2, user_id: 1>
Permission
Permission
XXXXXXXXXXXXXXXXXXXXXXXXX    Feed Observer - after_destroy      XXXXXXXXXXXXXXXXXXXXXXXXXXX

The problem with this is that in my permissions controller there are two methods that can delete a permission object, destory and leaveproject..

In the observer, how can I determine what method was called that resulted in the Feed observer being called?

Thanks


Well you can't know, but i don't it should be that hard to find out.

its after destroy, if you are following conventions, it should be in the feeds_controller.rb ie FeedsController#destroy , or in case of :dependent => :destroy associations, it should be in the associations controller in the destroy action.

another simple way is too raise a dummy error using the ruby raise method, and walk your self through the stack trace


Try Kernel#caller which will return the backtrace at that point in the execution stack. Try it like this:

def after_destroy(record)
  Rails.logger.info caller.join("\n")
  ...

You'll get a bit of output but if you skip over the rails framework stuff you should find your controller code.


If this is really important for you, a much simpler solution is probably to create your own method on the model class to call the destroy and directly performs any cleanup stuff. This function could then receive additional info about caller. Something like this could work:

class Work < ActiveRecord::Base
  def destroy_work(from)
    self.destroy
    Rails.logger.info "The work with the id of #{id} got destroyed by #{from}"
  end
end

By not relying on fancy meta-programming (like inspecting the call stack) you make your program much more resilient and also much easier to understand. The same applies for callbacks and even more so external observer classes. In the original model, there are usually only little traces of the existence of the callbacks (if at all). This makes analyzing behavior very complicated and error prone as you can easily overlook potentially important parts of your business logic. By implementing straight forward functions, you make your logic easier to understand as it follows a simple straight line.

If in doubt, always the stupidest and simplest thing that could possibly work. You generally have to be twice as clever to debug code as you have to be to write it. So doing clever things might lead to effectively unmaintainable code later on as people are just not clever enough to understand your logic flows.

0

精彩评论

暂无评论...
验证码 换一张
取 消