Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rails-decorators

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rails-decorators

  • 0.1.3
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Rails::Decorators

Using Rails engines extensively, we needed a way to customize behavior for implementations of the platform. Rails provides a great mechanism for views and assets, but doesn't offer any functionality to handle controller/model/lib overriding/customizing. The suggested mechanism in the documentation is class_eval or ActiveSupport::Concern. Our preferred method for this is module prepending, which is cleaner than class_eval in that it avoids alias method chaining and becomes part of the ancestor chain.

We also want junior developers to be able to jump in and be productive ASAP - not necessarily requiring they learn the techniques of class_eval to fix a bug or get a simple task done. Yes, we educate and promote this as the developer grows, but we want the barriers to contribution as low as possible.

We like the ActiveSupport::Concern API, so this library mimics the API of ActiveSupport::Concern and layers on top some niceties for the specific task of customizing a Rails engine. Also, we don't like having to store decorated behavior in a separate directory (like https://github.com/parndt/decorators). Storing decorations in the same place as new classes makes it much easier to see the overall picture of how the engine has been customized/extended in one shot.

Usage

Say we have a class in an engine like so:

# in ecommerce/app/models/ecommerce/product.rb
module Ecommerce
  class Product < ApplicationRecord
    def price
      skus.first.price
    end
  end
end

Rails::Decorators allows customizing this class like so:

# in Rails.root/app/models/ecommerce/product.decorator
module Ecommerce
  decorate Product do
    decorated do
      # Class methods may be called here. Evaluates after prepending module.
      attr_writer :on_sale
    end

    class_methods do
      # Methods defined here extend/decorate static methods on the
      # decorated class.
      def sorts
        super + ['discount_rate']
      end
    end

    # Methods defined here extend/decorate instance methods on the
    # decorated class.
    def price
      result = super
      result *= discount_rate if on_sale?
      result
    end
  end
end

Rails::Decorators achieves this in a manner similar to ActiveSupport::Concern - it dynamically creates a module out of the block passed, and then prepends that into the original class. The above is equivalent to (note that this would need to be required using require_dependency as well):

# in Rails.root/app/models/ecommerce/product_decorator.rb
module Ecommerce
  class Product
    module Decorator
      module ClassMethods
        # Methods defined here extend/decorate static methods on the
        # decorated class.
        def sorts
          super + ['discount_rate']
        end
      end

      # Methods defined here extend/decorate instance methods on the
      # decorated class.
      def price
        result = super
        result *= discount_rate if on_sale?
        result
      end
    end
  end

  Product.send(:prepend, Product::Decorator)
  Product.singleton_class.send(:prepend, Product::Decorator::ClassMethods)
  Product.class_eval do
    # Class methods may be called here. Evaluates after prepending module.
    attr_writer :on_sale
  end
end

You can also decorate more than one class at a time:

# in Rails.root/app/models/ecommerce/navigable.decorator
module Ecommerce
  decorate Product, Category, Page do
    def generate_slug
      # my custom logic here
    end
  end
end

Other engines may want to namespace their customizations so as not to collide with further customizations:

# in ecommerce_blog/app/models/ecommerce/product.decorator
module Ecommerce
  decorate Product, with: 'blog' do
    def blog_entries
      BlogEntry.for_product(id)
    end
  end
end

It is strongly suggested you update your editor of choice to use Ruby syntax highlighting on *.decorator files.

Installation

Add this line to your application's Gemfile:

gem 'rails-decorators'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails-decorators

Contributing

Contribution directions go here.

License

The gem is available as open source under the terms of the MIT License.

FAQs

Package last updated on 06 Nov 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc