Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails before_filter vs ruby's initialize

Just a thought in my mind. what is the difference the following

before_filter

class ApplicationController < ActionController::Base
  before_filter :foo
  def foo
    @mode = Model.new
  end
end

ruby initialize

class ApplicationController < ActionController::Base
  def initialize
    foo
  end

  def foo
    @mode = Model.new
  end
end
  1. Does ruby's initialize method work as expected in rails?
  2. If yes, then can we use initialize in place a filter has to be applied to all actions in a controller?
like image 914
CuriousMind Avatar asked Sep 02 '13 15:09

CuriousMind


Video Answer


2 Answers

For each request, you do get a fresh instance of ApplicationController, but the big no-no here is that you're attempting to override core behavior of ActionController::Base#initialize without calling the parent behavior.

ApplicationController < ActionController::Base

  def initialize
    super # this calls ActionController::Base initialize
    init_foo
  end

  private

  def init_foo
    @foo = Foo.new
  end
end

This is not idiomatic Rails behavior though. They give you before_filter for a reason; so use it.

like image 178
Mulan Avatar answered Sep 19 '22 07:09

Mulan


I believe this was covered in Practical Object-Oriented Design in Ruby by Sandi Metz.

Suppose you are designing a base class for other developers/users, and want to allow them to hook into various steps in a procedure (e.g. initialization.) In general, there are two ways:

  1. Break up the procedure into small methods, and (in the documentation) remind users to use super whenever they override a method.
  2. Include calls to various empty hook methods that users can override with custom functionality.

(I believe that these are variations of the Template Method pattern.)

The second way requires more effort on your part and less effort for your users.

In this specific case, before_filter provides a cleaner way to attach multiple hooks and encourages you to break up hooks into single-responsibility methods with meaningful names. This becomes more important in applications that use more controller inheritance.

like image 31
James Lim Avatar answered Sep 23 '22 07:09

James Lim