5.6. Using S2Container with Rails

5.6.1. Environment

  • Ruby-1.8.7
  • Rails-2.3.2
  • WEBrick-1.3.1

5.6.2. Setup

5.6.2.1. Installation of Initializer

Please save the S2Rails initialization file in the config/initializers directory of the Rails project directory.

5.6.2.2. Setting of ApplicationController

Please add the following process method to the ApplicationController class defined in app/controllers/application_controller.rb of the Rails project directory.

class ApplicationController < ActionController::Base
  ...
  def self.process(request, response)
    container = S2Rails.get_s2container(request)
    if container && container.has_component_def(self)
      result = container.get(self).process(request, response)
      begin
        container.destroy
      rescue => e
        s2logger.error(self) {"destroy of s2container failed. #{e.message} #{e.backtrace}"}
      end
      return result
    else
      return super # new.process(request, response);
    end
  end
  ...
end

5.6.3. Summary

In S2Rails configuration file (s2rails.rb) installed by the setup, the following three processing is executed.

  • Initialization of S2Container
  • Define the Rack Middleware for S2Rails.
  • Define the instantiate_controller method, it instantiate ActionController using S2Container.

In S2Rails::Rack Middleware, S2ApplicationContext has been initialized.
The instantiate_controller method is called by the process method which had been added to ApplicationController at the setup.

S2Container that generates ActionController is generated with S2ApplicationContext initialized with S2Rails::Rack Middleware. The controller name is used for namespace specified when S2Container is generated. Moreover, namespace set to the S2Rails.IncludeNamespaces constant is used. %w[services daos models interceptors dbi] is set to the S2Rails.IncludeNamespaces constant as a default value. S2Container with the component included in these namespace is generated at each request.

[Caution]Caution

"Eager loading" of the class definition is executed at each request even when the environmental setting is "Development" because the component registration is executed in S2ApplicationContext at the time of loadding the class definition.


5.6.4. Dependency Injection

As an example, Let's create sample conrtoller.

% ruby script/generate controller sample
      ...
      create  app/controllers/sample_controller.rb
      ...
%

Please edit the sample controller as follows. It registers as a component by the s2component method. When the namespace option is omitted, controller name "sample" is used for namespace. The accessor method that receives the hello component is defined with attr_accessor method.

  • app/controllers/sample_controller.rb
class SampleController < ApplicationController
  s2component
  attr_accessor :hello
  def index
    @result = @hello.world
  end
end

Next, please make the template file of the index action.

  • app/views/sample/index.rhtml
<%=h @result %>;

Let's make the Hello class to the app/models directory. By specifying the namespace as "models", the Hello component can be used also with ActionController other than SampleController. Namespace used by all requests is set to the S2Rails.IncludeNamespaces constant array. To use it only with SampleController, namespace should be set as "sample".

  • app/models/hello.rb
class Hello
  s2comp :namespace => 'models'
  def world
    return 'Hello World'
  end
end

When you access "http://localhost:3000/sample/index" by a browser, it will be displayed as "Hello World".



© Copyright The Seasar Foundation and the others 2008-2009, all rights reserved.