Blog
what did i learn today
accessing current_user in models
Up until now i was able to somehow circumvent the need to access the current-user in the model, by calling methods from the controllers and handing down the current-user. In the MVC pattern, the model should know as little as possible about things the controller handles. But now, i need a method that will check :before_save what has changed, and by whom, and will log that into another table (model). So i am going to create an Observer class, that needs to access the model on the one hand, but needs to know the current-user on the other hand. First I found a very dirty but working solution. Put this in application.rb: [ruby] around_filter :you_dont_have_bloody_clue protected def you_dont_have_bloody_clue klasses = [ActiveRecord::Base, ActiveRecord::Base.class] methods = ["session", "cookies", "params", "request"] methods.each do |shenanigan| oops = instance_variable_get(:"@_#{shenanigan}") klasses.each do |klass| klass.send(:define_method, shenanigan, proc { oops }) end end yield methods.each do |shenanigan| klasses.each do |klass| klass.send :remove_method, shenanigan end end end [/ruby] This was credited to Pratik Naik, but at the same time highly NOT recommended by him. It seems a bit like a bulldozer approach. Actually it is nice to know such things are possible, and how to achieve it, but it (kind of) breaks the MVC pattern. So i looked further for a nicer solution. I found a really simple one here, and adapted it to my needs: [ruby] class User < ActiveRecord::Base cattr_accessor :current_user def self.current_user @current_user ||= User.new("dummy-user") end ... end class ApplicationController < ActionController::Base include AuthenticatedSystem before_filter { |c| User.current_user = session[:user] } end [/ruby] And now, inside each class, i can just use [ruby]User.current_user[/ruby]. I overwrite the current_user class method, so i don't have to set the user manually during tests (is that clean?). I am not sure if this is the best solution. I found a few more complicated ones, but this seems to fit me the best.