'controller'에 해당되는 글 1건

  1. [2007/02/08] Rails Application의 컨트롤러를 모듈화시킬 때의 주의사항

Rails Application의 컨트롤러를 모듈화시킬 때의 주의사항

[Development]
Rails Appliation이 커지다보면 컨트롤러를 모듈화해서 분리시켜야할 필요가 있다. 예를 들어 100개의 컨트롤러가 있다고 할 때, 이 파일들이 $RAILS_APP/app/controller 디렉토리에 들어있다고 하면 관리의 측면에서 매우 비효율적이 되기 때문이다. 이 글에서는 컨트롤러를 모듈화시

1. 컨트롤러의 생성.
Rails의 script를 통해서 컨트롤러를 생성할 경우, 컨트롤러명 앞에 모듈 이름을 붙여주면 된다.
예를 들어 Bar::Foo::TestController 라는 컨트롤러를 만들려면,
[code]
ruby script/generate controller bar/foo/test
[/code]
라고 하면 된다. 이렇게 생성된 컨트롤러 파일은 $RAILS_APP/app/controller/bar/foo/test_controller.rb 가 되고, 소스는 다음과 같다.
[code type=ruby]
class Bar::Foo::TestController < ApplicationController
end
[/code]

2. 컨트롤러의 활용.
위와 같이 모듈화 시킨 컨트롤러는 단순히 관리에만 편리한 것은 아니다. 모듈화시킬 때, 얻을 수 있는 이점 중의 하나는 컨트롤러를 기능별로 묶을 수 있다는 점이다. application.rb 파일에 선언한 method나 상수는 전체 컨트롤러에서 사용될 수 있다. 이것은 컨트롤러를 생성할 때, application.rb에서 선언된 ApplicationController 를 상속해서 선언하기 때문이다. 이와 마찬가지로 기능별로 base 컨트롤러를 만든 후, 그 컨트롤러를 상속받아서 하위 컨트롤러를 만들 경우 중복되는 소스 코드없이 깔끔한 컨트롤러를 만들 수 있다.

예를 들어 관리자 페이지를 만든다고 가정하자. 관리자 페이지에는 여러가지 기능들이 있겠지만, 우선적으로 관리자 페이지에 대한 접근 권한을 체크해야할 것이다. 만약 컨트롤러를 모두 분리해서 사용한다면, ApplicationController에 validation 코드를 작성하고, 그것을 각 admin 관련 코드에서 before_filter로 불러줘야 한다. 이를 소스 코드로 풀어보면,
[code type=ruby]
# app/controller/application.rb
class ApplicationController < ActionController::Base
  def validates_admin
    # admin validatation code
  end
end

# app/controller/admin_user_controller.rb
class AdminUserControlller < ApplicationController
  before_filter :validates_admin
end

# app/controller/admin_log_controller.rb
class AdminLogController < ApplicationController
  before_filter :validates_admin
end
[/code]

하지만, 만약 admin이라는 모듈로 admin 관련 기능을 묶는 다면 (물론 하위로 더 세분화시킬 수도 있다.)
[code type=ruby]
# app/controller/admin/base_controller.rb
class Admin::BaseController < ApplicationController
  before_filter :validates_admin

private
  def validates_admin
   # admin validatation code
  end
end

# app/controller/admin/user_controller.rb
module Admin
  class UserController < BaseController
    # Nothing to do
  end
end
[/code]

위와 같이 상속받는 클래스들에서는 코드를 추가할 필요가 없게된다. 여기서는 관리자 인증이라는 간단한 예를 들었지만, 기능이 복잡해지고 추가될 수록 이렇게 관리한 컨트롤러는 나중에 빛을 발할 것이다. ^^;

3. 주의할 점
위와 같이 모듈화 시켜서 사용할 경우에 주의할 점은 모델명과의 충돌이다. 예를 들어서 우리가 Admin이라는 모델 클래스를 갖고 있다면 어떻게 될까? 관리자 코드의 안에서는 module Admin이 Admin 모델 클래스를 감추게 되기 때문에, 접근할 수가 없게 된다. 즉, 다음과 같은 코드는 find method가 없다는 에러를 발생시킨다.

[code type=ruby]
# app/controller/admin/user_controller.rb
module Admin
  class UserController < BaseController
   admins = Admin.find(:all)  # => module Admin에는 find method가 없으므로 에러를 발생시킴.
  end
end
[/code]

따라서 모듈화시켜서 사용할 경우에는 모델명과의 충돌을 피하는 것이 좋다. 이 점만 유의한다면, Rails Application이 커지더라도, 유연하게 컨트롤러를 관리할 수 있을 것이다.





2007/02/08 18:40 2007/02/08 18:40