views:

21

answers:

2

In one of the controller, I need a specific layout. I added layout at the beginning. It works well.

But if I add an initialize function for some controller-based variable. Rails seems just ignore the layout command.

Is anyone have same problem? How can I fix it?

class AdminsController < ApplicationController

  layout "layout_admins"

  def initialize
    @Title = "Admins"
  end

  def index
    ....... some code here
  end
end
+4  A: 

initialize is used internally to Rails to, well, initialize a new instance of your controller so it can then serve requests on it. By defining this method in this particular manner, you are breaking Rails.

There is a way through! A light at the end of the tunnel. A pot of gold at the end of the rainbow:

def initialize
  @title = "Admins"
  super
end

See that little super call there? That'll call the superclass's initialize method, doing exactly what Rails would do otherwise. Now that we've covered how to do it your way, let's cover how to do it the "officially sanctioned" Rails way:

class AdminsController < ApplicationController
  before_filter :set_title


  # your actions go here

  private      
    def set_title
      @title = "Title"
    end
end

Yes, it's a little more code but it'll result in less frustration by others who gaze upon your code. This is the conventional way of doing it and I strongly encourage following conventions rather than doing "magic".

Ryan Bigg
Thanks for the clear explanation. I don't mean to break Rails magic. >.< Seems I still have a long time before getting out from the tunnel... :P
siulamvictor
It's a Ruby behavior, not really a Rails issue. You're breaking Rails as a side effect of being built on top of Ruby, but initialize is a Ruby method. ;)
Simone Carletti
+2  A: 

I'm not sure exactly how layout works its magic, but I'm willing to bet it's in a yield block in the ActionController#initialize method. So your overriding of initialize would explain the problem.

Looks like you have too options here:

  1. Close out your new definition with super to call the ActionController initialize which should use the layout defined in the class.

    eg:

    def initialize
      @Title = "Admins"
      super
    end
    
  2. Use a before filter to initialize your variables. This is the Rails Way of initializing values in a controller

    class AdminsController < ApplicationController
      layout "layout_admins"
    
    
      before_filter :set_title
      def set_title
        @Title = "Admins"
      end
    
    
      def index
        ....... some code here
      end
    end
    
EmFi
Thanks buddy. :)
siulamvictor