Add decorates_assigned method to controllers

This commit is contained in:
Andrew Haines 2013-02-07 00:39:42 +00:00
parent c6ca04fedd
commit afa97bb401
5 changed files with 116 additions and 2 deletions

View File

@ -21,6 +21,7 @@ require 'draper/decorated_association'
require 'draper/helper_support'
require 'draper/view_context'
require 'draper/collection_decorator'
require 'draper/decorates_assigned'
require 'draper/railtie' if defined?(Rails)
module Draper
@ -28,6 +29,7 @@ module Draper
base.class_eval do
include Draper::ViewContext
extend Draper::HelperSupport
extend Draper::DecoratesAssigned
before_filter do |controller|
Draper::ViewContext.clear!

View File

@ -0,0 +1,39 @@
module Draper
module DecoratesAssigned
# @overload decorates_assigned(*variables, options = {})
# Defines a helper method to access decorated instance variables.
#
# @example
# # app/controllers/articles_controller.rb
# class ArticlesController < ApplicationController
# decorates_assigned :article
#
# def show
# @article = Article.find(params[:id])
# end
# end
#
# # app/views/articles/show.html.erb
# <%= article.decorated_title %>
#
# @param [Symbols*] variables
# names of the instance variables to decorate (without the `@`).
# @param [Hash] options
# see {Factory#initialize}
def decorates_assigned(*variables)
factory = Draper::Factory.new(variables.extract_options!)
variables.each do |variable|
undecorated = "@#{variable}"
decorated = "@decorated_#{variable}"
define_method variable do
return instance_variable_get(decorated) if instance_variable_defined?(decorated)
instance_variable_set decorated, factory.decorate(instance_variable_get(undecorated))
end
helper_method variable
end
end
end
end

View File

@ -0,0 +1,71 @@
require 'spec_helper'
module Draper
describe DecoratesAssigned do
let(:controller_class) do
Class.new do
extend DecoratesAssigned
def self.helper_method(method)
helper_methods << method
end
def self.helper_methods
@helper_methods ||= []
end
end
end
describe ".decorates_assigned" do
it "adds helper methods" do
controller_class.decorates_assigned :article, :author
expect(controller_class.instance_methods).to include :article
expect(controller_class.instance_methods).to include :author
expect(controller_class.helper_methods).to include :article
expect(controller_class.helper_methods).to include :author
end
it "creates a factory" do
Factory.should_receive(:new).once
controller_class.decorates_assigned :article, :author
end
it "passes options to the factory" do
options = {foo: "bar"}
Factory.should_receive(:new).with(options)
controller_class.decorates_assigned :article, :author, options
end
describe "the generated method" do
it "decorates the instance variable" do
source = double
factory = double
Factory.stub new: factory
controller_class.decorates_assigned :article
controller = controller_class.new
controller.instance_variable_set "@article", source
factory.should_receive(:decorate).with(source).and_return(:decorated)
expect(controller.article).to be :decorated
end
it "memoizes" do
factory = double
Factory.stub new: factory
controller_class.decorates_assigned :article
controller = controller_class.new
factory.should_receive(:decorate).once
controller.article
controller.article
end
end
end
end
end

View File

@ -1,6 +1,8 @@
class PostsController < ApplicationController
decorates_assigned :post
def show
@post = Post.find(params[:id]).decorate
@post = Post.find(params[:id])
end
def mail

View File

@ -1 +1 @@
<%= render @post %>
<%= render post %>