开发者

Rails 3 - how to organize / split up bloated controllers?

I've been working on a CMS app to sharpen up my开发者_如何学运维 skills and the controllers are getting quite bloated with the definitions. I know it's possible to store stuff in lib/whatever.rb and then use require and include, but that doesn't quite work with controllers - at least, in my case, where I have before_filters. Without the definitions right in the controller, before_filters refuse to work.

Do all the defs HAVE to go in the controller or is there a way to take them out? (They are specific to that controller so they can't go in application controller.


You can do a lot of things with mixin modules that will add behavior to an existing controller, or you can try and come up with a class hierarchy that will allow the controllers to inherit the required methods from their parent class.

In most applications I sub-class ApplicationController at least once in order to enforce some standards in certain contexts. For instance, all controllers relating to a Project would inherit from ProjectController::Base:

class ProjectController::Base < ApplicationController
  before_filter :must_be_logged_in
  before_filter :load_project

protected
  def load_project
    @project = Project.find(params[:project_id] || params[:id])

  rescue ActiveRecord::RecordNotFound
    render(:template => 'not_found')
  end

  def must_be_logged_in
    # ...
  end
end


The augmentation-plugin (it's rather a snippet) could be a solution for you.

What it does (add some methods to Object/Module)

class ::Object
  def self.augment(*mods)
    include *mods
    mods.each {|mod| class_eval &mod.augmentation }
  end
end

class ::Module
  def augmentation(&block)
    @augmentation ||= block
  end
end

What it allows you to do

# app/controllers/your_controller.rb
class YourController
  augment YourController::Stuff

  ...
end

# app/controllers/your_controller/stuff.rb
module YourController::Stuff
  augmentation do
    before_filter :something

    def something
      ...
    end
  end
end

You need to make sure that subfolders of folders in /app are included in Rails' autoload paths.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜