rails3 gem: acts_as_something

前端 未结 1 1642
面向向阳花
面向向阳花 2021-02-02 03:30

I\'m trying to extract some common code into a gem.

I\'m thinking that acts_as_somethingis a good strategy for simple re-use.

Is there a good tuto

相关标签:
1条回答
  • 2021-02-02 03:53

    UPDATE: I've added a blog post based on this answer, but with much more detail: http://thoughtsincomputation.com/posts/coding-an-acts_as-gem-for-rails-3

    --

    I'm not aware of another tutorial source off the top of my head, but here are some general tips.

    Rails 3 makes use of a really useful feature called Railtie - see http://api.rubyonrails.org/classes/Rails/Railtie.html .

    So, if I were implementing an acts_as_* gem, I'd start there. My railtie might look something like:

    # lib/acts_as_awesome/railtie.rb
    require 'rails'
    require 'acts_as_awesome'
    
    module ActsAsAwesome
      class Railtie < Rails::Railtie
        config.to_prepare do
          ApplicationController.send(:extend, ActsAsAwesome::Hook)
        end
      end
    end
    

    and the ActsAsAwesome::Hook code:

    # lib/acts_as_awesome/hook.rb
    module ActsAsAwesome::Hook
      def acts_as_awesome(*args)
        options = args.extract_options!
        # do the things that make the controller awesome.
        include ActsAsAwesome::InstanceMethods
        before_filter :an_awesome_filter
      end
    end
    

    I feel the concepts here are sound and have used similar processes before. Basically, it would tell Rails to execute the to_prepare block once during production and before each request in development (we want that because ApplicationController will be reloaded at those times, potentially wiping out our hook method); and the hook is just that: it adds a hook to all controllers (or rather, all controllers that extend ApplicationController) to allow the user to introduce the real "Awesome" code into their controllers without otherwise affecting controllers that don't need it.

    The #acts_as_awesome hook doesn't, in itself, convey the Awesome functionality. That's because not all controllers might need this functionality. Instead, the method is responsible for introducing the real awesome stuff, via the ActsAsAwesome::InstanceMethods module. This way, the user only gets the Awesome functionality if they explicitly call the acts_as_awesome method. It also adds a before filter to the controller to demonstrate that the code in this method would be evaluated exactly the same as if it were in the target controller class itself.

    This technique should work exactly the same if you're targeting models instead of controllers: just inject your hook into ActiveRecord::Base. As AR:B is only loaded at Rails boot, you should probably be able to put that into an initializer (refer to the Railtie docs), but I reserve the right to be mistaken here.

    A gotcha concerning the railtie: the documentation reads as if it should have been autodetected, but I often have problems with this. To get around it, simply require the railtie from your gem's main source file (in the above example, that would be lib/acts_as_awesome.rb).

    You can see the entire ActsAsAwesome source in all its glory at my github account: http://github.com/sinisterchipmunk/acts_as_awesome

    I hope this is helpful. Your question was somewhat high-level so a high-level response is the best I can do.

    -Colin MacKenzie IV

    http://thoughtsincomputation.com

    @sinisterchipmnk

    0 讨论(0)
提交回复
热议问题