2012-07-13 17:39:23 +00:00
|
|
|
# -*- encoding : utf-8 -*-
|
|
|
|
require "decorates_before_rendering/version"
|
|
|
|
require 'active_support/core_ext/string/inflections'
|
|
|
|
require 'active_support/core_ext/class/attribute'
|
2012-10-18 01:24:20 +00:00
|
|
|
require 'active_support/concern'
|
2012-07-13 17:39:23 +00:00
|
|
|
|
|
|
|
# Decorates the specified fields. For instance, if you have
|
|
|
|
#
|
|
|
|
# class StuffController < ApplicationController
|
|
|
|
# include DecoratesBeforeRendering
|
|
|
|
#
|
|
|
|
# decorates :thing_1, :thing_2
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# @thing_1 and @thing_2 will be decorated right before a rendering occurs.
|
|
|
|
#
|
2012-10-01 13:30:15 +00:00
|
|
|
# You can also specify the decorator you wish to use for a particular instance variable:
|
|
|
|
#
|
|
|
|
# class StuffController < ApplicationController
|
|
|
|
# include DecoratesBeforeRendering
|
|
|
|
#
|
|
|
|
# decorates :thing_1, :with => ThingListDecorator
|
|
|
|
# decorates :thing_2
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# @thing_1 will be a ThingListDecorator (or contain them), and @thing_2 will be a Thing2Decorator.
|
|
|
|
#
|
2013-01-17 12:31:14 +00:00
|
|
|
# For Draper 1.0 and above, collection elements are no longer decorated with
|
|
|
|
# Decorator.decorate(collection), but with Decorator.decorate_collection(collection).
|
|
|
|
# Specify that you want to decorate a collection, and with what decorator, with this syntax:
|
|
|
|
#
|
|
|
|
# class StuffController < ApplicationController
|
|
|
|
# include DecoratesBeforeRendering
|
|
|
|
#
|
|
|
|
# decorates_collection :things_1, :with => ThingListDecorator
|
|
|
|
# end
|
|
|
|
#
|
2012-07-13 17:39:23 +00:00
|
|
|
module DecoratesBeforeRendering
|
2012-10-18 01:24:20 +00:00
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
|
|
|
included do
|
|
|
|
class_attribute :__decorates__, :instance_writer => false
|
2013-01-17 12:31:14 +00:00
|
|
|
class_attribute :__decorates_collection__, :instance_writer => false
|
2012-09-21 18:07:12 +00:00
|
|
|
|
2012-10-18 01:24:20 +00:00
|
|
|
class_eval do
|
|
|
|
def self.decorates(*args)
|
|
|
|
options = args.extract_options!
|
|
|
|
|
|
|
|
self.__decorates__ ||= []
|
|
|
|
self.__decorates__ << [ args.map { |i| "@#{i}" }, options ]
|
|
|
|
end
|
2013-01-17 12:31:14 +00:00
|
|
|
|
|
|
|
def self.decorates_collection(*args)
|
|
|
|
options = args.extract_options!
|
|
|
|
|
|
|
|
raise ArgumentError, ":with is required for now" if !options[:with]
|
|
|
|
|
|
|
|
self.__decorates_collection__ ||= []
|
|
|
|
self.__decorates_collection__ << [ args.map { |i| "@#{i}" }, options ]
|
|
|
|
end
|
2012-07-13 17:39:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def render(*args)
|
|
|
|
__decorate_ivars__
|
|
|
|
super(*args)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def __decorate_ivars__
|
2013-01-17 12:31:14 +00:00
|
|
|
return if (__decorates__.nil? || __decorates__.empty?) and
|
|
|
|
(__decorates_collection__.nil? || __decorates_collection__.empty?)
|
|
|
|
|
|
|
|
if !__decorates__.nil?
|
|
|
|
__decorate_ivar_names__(__decorates__) do |ivar_name, ivar, options|
|
|
|
|
decorator = options.key?(:with) ? options.fetch(:with) : __decorator_for__(ivar)
|
|
|
|
decorated = decorator.decorate(ivar)
|
|
|
|
instance_variable_set(ivar_name, decorated)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if !__decorates_collection__.nil?
|
|
|
|
__decorate_ivar_names__(__decorates_collection__) do |ivar_name, ivar, options|
|
|
|
|
decorated = options.fetch(:with).decorate_collection(ivar)
|
|
|
|
instance_variable_set(ivar_name, decorated)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-07-13 17:39:23 +00:00
|
|
|
|
2013-01-17 12:31:14 +00:00
|
|
|
def __decorate_ivar_names__(ivars)
|
|
|
|
ivars.each do |ivar_names, options|
|
2012-09-21 18:07:12 +00:00
|
|
|
ivar_names.each do |ivar_name|
|
2012-10-18 01:24:20 +00:00
|
|
|
ivar = instance_variable_get(ivar_name)
|
|
|
|
if ivar
|
2013-01-17 12:31:14 +00:00
|
|
|
yield ivar_name, ivar, options
|
2012-09-21 18:07:12 +00:00
|
|
|
end
|
|
|
|
end
|
2012-07-13 17:39:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def __decorator_for__(ivar)
|
2012-09-21 18:07:12 +00:00
|
|
|
__decorator_name_for__(ivar).constantize
|
2012-07-13 17:39:23 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def __decorator_name_for__(ivar)
|
|
|
|
"#{__model_name_for__(ivar)}Decorator"
|
|
|
|
end
|
|
|
|
|
|
|
|
def __model_name_for__(ivar)
|
|
|
|
if ivar.respond_to?(:model_name)
|
2012-10-18 01:24:20 +00:00
|
|
|
source = ivar
|
2012-07-13 17:39:23 +00:00
|
|
|
elsif ivar.class.respond_to?(:model_name)
|
2012-10-18 01:24:20 +00:00
|
|
|
source = ivar.class
|
2012-07-13 17:39:23 +00:00
|
|
|
else
|
|
|
|
raise ArgumentError, "#{ivar} does not have an associated model"
|
2012-10-18 01:24:20 +00:00
|
|
|
end
|
2012-07-13 17:39:23 +00:00
|
|
|
|
2012-10-18 01:24:20 +00:00
|
|
|
source.model_name
|
2012-07-13 17:39:23 +00:00
|
|
|
end
|
|
|
|
end
|