├── lib ├── decent_decoration │ ├── version.rb │ └── decorate.rb └── decent_decoration.rb ├── spec ├── spec_helper.rb ├── fixtures │ ├── decorators.rb │ ├── models.rb │ ├── controllers.rb │ └── fake_rails_application.rb ├── integration │ ├── draper_spec.rb │ └── rails_application_spec.rb └── decoration_spec.rb ├── Rakefile ├── Gemfile ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.txt ├── decent_decoration.gemspec ├── README.md └── Gemfile.lock /lib/decent_decoration/version.rb: -------------------------------------------------------------------------------- 1 | module DecentDecoration 2 | VERSION = "0.0.6" 3 | end 4 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | require 'decent_decoration' 3 | require 'coveralls' 4 | 5 | Coveralls.wear! 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'rspec/core/rake_task' 3 | RSpec::Core::RakeTask.new(:spec) 4 | 5 | task :default => :spec 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in decent_decorate.gemspec 4 | gemspec 5 | 6 | gem 'coveralls', require: false 7 | -------------------------------------------------------------------------------- /lib/decent_decoration.rb: -------------------------------------------------------------------------------- 1 | require "decent_decoration/decorate" 2 | require "decent_decoration/version" 3 | 4 | ActiveSupport.on_load(:action_controller) do 5 | extend DecentDecoration::ControllerMethods 6 | end 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | InstalledFiles 7 | _yardoc 8 | coverage 9 | doc/ 10 | lib/bundler/man 11 | pkg 12 | rdoc 13 | spec/reports 14 | test/tmp 15 | test/version_tmp 16 | tmp 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 1.9.3 4 | - 2.0.0 5 | - jruby-19mode 6 | - rbx-19mode 7 | notifications: 8 | email: 9 | recipients: 10 | - pewniak747@gmail.com 11 | - bartosz.kopinski@netguru.pl 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.0.6 4 | 5 | * fixed `decent_exposure` dependency [@madsheep] 6 | 7 | ## v0.0.5 8 | 9 | * relaxed actionpack dependency allowing usage with rails 4 10 | * fixed deprecation warnings in specs 11 | -------------------------------------------------------------------------------- /spec/fixtures/decorators.rb: -------------------------------------------------------------------------------- 1 | require 'delegate' 2 | require 'draper' 3 | 4 | class ConferenceDecorator < SimpleDelegator 5 | def decorated_object 6 | __getobj__ 7 | end 8 | end 9 | 10 | class CoolConferenceDecorator < ConferenceDecorator 11 | end 12 | 13 | class AttendeeDecorator < Draper::Decorator 14 | def full_name 15 | "#{first_name} #{last_name}" 16 | end 17 | 18 | def self.find(id) 19 | Attendee.find(id) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/integration/draper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'fixtures/fake_rails_application' 3 | require 'rspec/rails' 4 | 5 | describe AttendeesController, type: :controller do 6 | before do 7 | get '/attendee/dave' 8 | end 9 | 10 | it "should be a decorator" do 11 | controller.view_context.attendee.should be_instance_of(AttendeeDecorator) 12 | end 13 | 14 | it "should be a decorator in collection" do 15 | controller.view_context.attendees.each do |attendee| 16 | attendee.should be_instance_of(AttendeeDecorator) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/fixtures/models.rb: -------------------------------------------------------------------------------- 1 | module Model 2 | extend ActiveModel::Naming 3 | 4 | def initialize(attrs={}) 5 | self.attributes = attrs 6 | end 7 | 8 | def attributes=(attributes) 9 | attributes.each { |k,v| send("#{k}=", v) } 10 | end 11 | 12 | def self.included(klass) 13 | def klass.find(id) 14 | new if id 15 | end 16 | 17 | def klass.scoped 18 | self 19 | end 20 | end 21 | end 22 | 23 | class Conference 24 | include Model 25 | attr_accessor :name, :location 26 | end 27 | 28 | class Attendee 29 | include Model 30 | attr_accessor :first_name, :last_name 31 | end 32 | -------------------------------------------------------------------------------- /spec/fixtures/controllers.rb: -------------------------------------------------------------------------------- 1 | class ConferencesController < ActionController::Base 2 | include Rails.application.routes.url_helpers 3 | 4 | expose_decorated(:conference) 5 | expose_decorated(:other_conference, model: Conference, decorator: CoolConferenceDecorator) 6 | 7 | def show 8 | render :text => "foo" 9 | end 10 | 11 | def new 12 | render :text => "foo" 13 | end 14 | end 15 | 16 | class AttendeesController < ActionController::Base 17 | include Rails.application.routes.url_helpers 18 | 19 | expose_decorated(:attendee) 20 | expose_decorated(:attendees) { [Attendee.new, Attendee.new] } 21 | 22 | def show 23 | render :text => "foo" 24 | end 25 | 26 | def new 27 | render :text => "foo" 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/fixtures/fake_rails_application.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/all' 2 | 3 | require 'decent_exposure' 4 | require 'decent_decoration' 5 | 6 | require 'action_controller' 7 | require 'action_dispatch' 8 | require 'active_model' 9 | 10 | module Rails 11 | class App 12 | def env_config; {} end 13 | def routes 14 | return @routes if defined?(@routes) 15 | @routes = ActionDispatch::Routing::RouteSet.new 16 | @routes.draw do 17 | get '/conferences/new' => "conferences#new" 18 | get '/conference/(:id)' => "conferences#show" 19 | get '/attendees/new' => "attendees#new" 20 | get '/attendee/(:id)' => "attendees#show" 21 | end 22 | @routes 23 | end 24 | def call(*args) 25 | routes.call(*args) 26 | end 27 | end 28 | def self.application 29 | @app ||= App.new 30 | end 31 | end 32 | 33 | require 'fixtures/models' 34 | require 'fixtures/decorators' 35 | require 'fixtures/controllers' 36 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014 netguru 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /decent_decoration.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'decent_decoration/version' 5 | 6 | Gem::Specification.new do |gem| 7 | gem.name = "decent_decoration" 8 | gem.version = DecentDecoration::VERSION 9 | gem.authors = ["Tomasz Pewiński"] 10 | gem.email = ["pewniak747@gmail.com"] 11 | gem.description = %q{Use decent_exposure with decorators (e.g. Draper)} 12 | gem.summary = %q{Use decent_exposure with decorators (e.g. Draper)} 13 | gem.homepage = "https://github.com/netguru/decent_decoration" 14 | 15 | gem.files = `git ls-files`.split($/) 16 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 17 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 18 | gem.require_paths = ["lib"] 19 | gem.add_runtime_dependency 'decent_exposure', '>= 2.0' 20 | gem.add_development_dependency 'rspec', '~> 2.13' 21 | gem.add_development_dependency 'rspec-rails', '~> 2.13' 22 | gem.add_development_dependency 'rails', '>= 3.2' 23 | gem.add_development_dependency 'activesupport', '>= 3.2' 24 | gem.add_development_dependency 'draper', '>= 1.0.0' 25 | end 26 | -------------------------------------------------------------------------------- /spec/integration/rails_application_spec.rb: -------------------------------------------------------------------------------- 1 | require 'fixtures/fake_rails_application' 2 | require 'rspec/rails' 3 | 4 | describe ConferencesController, type: :controller do 5 | before do 6 | get '/conference/RuPy' 7 | end 8 | 9 | describe "inside a view" do 10 | it "should be a decorator" do 11 | controller.view_context.conference.should be_instance_of(ConferenceDecorator) 12 | end 13 | 14 | it "should have decorated conference" do 15 | controller.view_context.conference.decorated_object.should be_instance_of(Conference) 16 | end 17 | 18 | it "should be specified decorator" do 19 | controller.view_context.other_conference.should be_instance_of(CoolConferenceDecorator) 20 | end 21 | 22 | it "should cache decorator" do 23 | controller.view_context.conference.object_id.should == controller.view_context.conference.object_id 24 | end 25 | 26 | it "should cache decorated object" do 27 | controller.view_context.conference.decorated_object.object_id.should == controller.view_context.conference.decorated_object.object_id 28 | end 29 | end 30 | 31 | describe "inside a controller" do 32 | it "should be undecorated object" do 33 | controller.conference.should be_instance_of(Conference) 34 | end 35 | 36 | it "should not be specified decorator" do 37 | controller.other_conference.should be_instance_of(Conference) 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/decent_decoration/decorate.rb: -------------------------------------------------------------------------------- 1 | module DecentDecoration 2 | class Decoration 3 | attr_accessor :name, :original_options 4 | private :original_options 5 | 6 | def initialize(name, options = {}) 7 | self.name = name 8 | self.original_options = options 9 | end 10 | 11 | def decorated_name 12 | "decorated_#{name}".to_sym 13 | end 14 | 15 | def options 16 | original_options.except(:decorator, :collection).tap do |h| 17 | h[:model] ||= name 18 | end 19 | end 20 | 21 | def decorator_class 22 | original_options.fetch(:decorator) { infer_decorator_class } 23 | end 24 | 25 | def decorate_method 26 | if decorate_collection? && decorator_class.respond_to?(:decorate_collection) 27 | :decorate_collection 28 | elsif decorator_class.respond_to?(:decorate) 29 | :decorate 30 | else 31 | :new 32 | end 33 | end 34 | 35 | private 36 | 37 | def infer_decorator_class 38 | "#{options[:model].to_s.classify}Decorator".constantize 39 | end 40 | 41 | def decorate_collection? 42 | (plural_name? && force_collection != false) || force_collection == true 43 | end 44 | 45 | def force_collection 46 | original_options[:collection] 47 | end 48 | 49 | def plural_name? 50 | plural_name == name && plural_name != singular_name 51 | end 52 | 53 | def plural_name 54 | name.to_s.pluralize.to_sym 55 | end 56 | 57 | def singular_name 58 | name.to_s.singularize.to_sym 59 | end 60 | end 61 | 62 | module ControllerMethods 63 | def expose_decorated(name, options = {}, &block) 64 | decoration = Decoration.new(name, options) 65 | 66 | decorator_class = decoration.decorator_class 67 | decorate_method = decoration.decorate_method 68 | decorated_name = decoration.decorated_name 69 | options = decoration.options 70 | 71 | expose(name, options, &block) 72 | expose(decorated_name) { decorator_class.public_send(decorate_method, public_send(name)) } 73 | 74 | helper Module.new do 75 | define_method(name) do 76 | public_send(decorated_name) 77 | end 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # decent_decoration 2 | [![Build Status](https://secure.travis-ci.org/netguru/decent_decoration.png?branch=master)](http://travis-ci.org/netguru/decent_decoration) 3 | [![Code Climate](https://codeclimate.com/github/netguru/decent_decoration.png)](https://codeclimate.com/github/netguru/decent_decoration) 4 | [![Coverage Status](https://coveralls.io/repos/netguru/decent_decoration/badge.png?branch=master)](https://coveralls.io/r/netguru/decent_decoration) 5 | [![Gem Version](https://badge.fury.io/rb/decent_decoration.png)](http://badge.fury.io/rb/decent_decoration) 6 | 7 | decent_decoration allows you to use excellent [decent_exposure][decent_exposure] gem with decorators. 8 | 9 | ## Installation 10 | 11 | Add this line to your application's Gemfile: 12 | 13 | ``` 14 | gem 'decent_decoration' 15 | ``` 16 | 17 | And then execute: 18 | 19 | ``` 20 | $ bundle 21 | ``` 22 | 23 | ## Usage 24 | 25 | ``` ruby 26 | # app/controllers/conferences_controller.rb 27 | # with decent_exposure 28 | class ConferencesController < ApplicationController 29 | expose(:conference) { ConferenceDecorator.new(build_conference) } 30 | 31 | private 32 | 33 | def build_conference 34 | # create new conference or fetch existing one 35 | end 36 | end 37 | 38 | # with decent_decoration 39 | class ConferencesController < ApplicationController 40 | expose_decorated(:conference) 41 | end 42 | ``` 43 | 44 | decent_decoration makes decorated objects accessible in views. They remain undecorated in your controllers. 45 | 46 | Define a decorator explicitly: 47 | 48 | ``` ruby 49 | # app/controllers/conferences_controller.rb 50 | class ConferencesController < ApplicationController 51 | expose_decorated(:conference, decorator: SponsoredConferenceDecorator) 52 | end 53 | ``` 54 | 55 | decent_decoration detect automatically if you want to decorate a collection. To circumvent this pass collection: true/false 56 | 57 | ``` ruby 58 | # app/controllers/conferences_controller.rb 59 | class ConferencesController < ApplicationController 60 | expose_decorated(:conferences, collection: false) 61 | end 62 | ``` 63 | 64 | decent_decoration supports most of the awesome [decent_exposure api][decent_exposure_api]. Read [more about it!][decent_exposure_api] 65 | 66 | ``` ruby 67 | # app/controllers/attendees_controller.rb 68 | class AttendeesController < ApplicationController 69 | expose_decorated(:conference) 70 | expose_decorated(:attendees, ancestor: :conference) 71 | end 72 | ``` 73 | 74 | You can use any decorator mechanism as long as `ConferenceDecorator` responds to `#decorate` or `#new`. Try [draper][draper]. 75 | 76 | ## Contributing 77 | 78 | 1. Fork it 79 | 2. Create your feature branch (`git checkout -b my-new-feature`) 80 | 3. Commit your changes (`git commit -am 'Add some feature'`) 81 | 4. Push to the branch (`git push origin my-new-feature`) 82 | 5. Create new Pull Request 83 | 84 | [decent_exposure]: https://github.com/voxdolo/decent_exposure 85 | [decent_exposure_api]: https://github.com/voxdolo/decent_exposure#usage 86 | [draper]: https://github.com/drapergem/draper 87 | 88 | Copyright © 2012–2014 [netguru](https://netguru.co). See LICENSE for further details. 89 | -------------------------------------------------------------------------------- /spec/decoration_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe DecentDecoration::Decoration do 4 | let(:klass) { DecentDecoration::Decoration } 5 | 6 | it "should be initialized with name" do 7 | subject = klass.new(:conference) 8 | subject.name.should == :conference 9 | end 10 | 11 | it "should be initialized with options" do 12 | subject = klass.new(:conference, { model: :conference }) 13 | subject.options.should == { model: :conference } 14 | end 15 | 16 | describe "#decorated_name" do 17 | it "should consist of name prepended by decorated" do 18 | klass.new(:conference).decorated_name.should == :decorated_conference 19 | end 20 | end 21 | 22 | describe "#decorator_class" do 23 | it "should infer the class from name" do 24 | klass.new(:conference).decorator_class.should == ConferenceDecorator 25 | end 26 | 27 | it "should use :decorator if passed" do 28 | klass.new(:conference, decorator: AttendeeDecorator).decorator_class.should == AttendeeDecorator 29 | end 30 | end 31 | 32 | describe "#decorate_method" do 33 | describe "when name is plural" do 34 | subject { klass.new(:conferences, decorator: decorator) } 35 | let(:decorator) { double } 36 | 37 | it "should be :decorate_collection if decorator supports it" do 38 | decorator.stub(:decorate_collection) 39 | subject.decorate_method.should == :decorate_collection 40 | end 41 | 42 | it "should be :decorate if decorator does not support :decorate_collection and supports :decorate" do 43 | decorator.stub(:decorate) 44 | subject.decorate_method.should == :decorate 45 | end 46 | 47 | it "should be :new if decorator does not support :decorate_collection or :decorate" do 48 | subject.decorate_method.should == :new 49 | end 50 | 51 | it "should be :decorate if decorator supports it and collection: false" do 52 | decorator.stub(:decorate) 53 | decorator.stub(:decorate_collection) 54 | subject = klass.new(:conferences, decorator: decorator, collection: false) 55 | subject.decorate_method.should == :decorate 56 | end 57 | end 58 | 59 | describe "when name is singular" do 60 | subject { klass.new(:conference, decorator: decorator) } 61 | let(:decorator) { double } 62 | 63 | it "should not be :decorate_collection even if decorator supports it" do 64 | decorator.stub(:decorate_collection) 65 | subject.decorate_method.should_not == :decorate_collection 66 | end 67 | 68 | it "should be :decorate_collection if decorator supports it and collection: true" do 69 | decorator.stub(:decorate) 70 | decorator.stub(:decorate_collection) 71 | subject = klass.new(:conference, decorator: decorator, collection: true) 72 | subject.decorate_method.should == :decorate_collection 73 | end 74 | 75 | it "should be :decorate if decorator supports it" do 76 | decorator.stub(:decorate) 77 | subject.decorate_method.should == :decorate 78 | end 79 | 80 | it "should be :new if decorator does not support :decorate" do 81 | subject.decorate_method.should == :new 82 | end 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | decent_decoration (0.0.6) 5 | decent_exposure (>= 2.0) 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | actionmailer (4.0.0) 11 | actionpack (= 4.0.0) 12 | mail (~> 2.5.3) 13 | actionpack (4.0.0) 14 | activesupport (= 4.0.0) 15 | builder (~> 3.1.0) 16 | erubis (~> 2.7.0) 17 | rack (~> 1.5.2) 18 | rack-test (~> 0.6.2) 19 | activemodel (4.0.0) 20 | activesupport (= 4.0.0) 21 | builder (~> 3.1.0) 22 | activerecord (4.0.0) 23 | activemodel (= 4.0.0) 24 | activerecord-deprecated_finders (~> 1.0.2) 25 | activesupport (= 4.0.0) 26 | arel (~> 4.0.0) 27 | activerecord-deprecated_finders (1.0.3) 28 | activesupport (4.0.0) 29 | i18n (~> 0.6, >= 0.6.4) 30 | minitest (~> 4.2) 31 | multi_json (~> 1.3) 32 | thread_safe (~> 0.1) 33 | tzinfo (~> 0.3.37) 34 | arel (4.0.0) 35 | atomic (1.1.13) 36 | builder (3.1.4) 37 | colorize (0.5.8) 38 | coveralls (0.6.7) 39 | colorize 40 | multi_json (~> 1.3) 41 | rest-client 42 | simplecov (>= 0.7) 43 | thor 44 | decent_exposure (2.2.1) 45 | diff-lcs (1.2.4) 46 | draper (1.2.1) 47 | actionpack (>= 3.0) 48 | activesupport (>= 3.0) 49 | request_store (~> 1.0.3) 50 | erubis (2.7.0) 51 | hike (1.2.3) 52 | i18n (0.6.5) 53 | mail (2.5.4) 54 | mime-types (~> 1.16) 55 | treetop (~> 1.4.8) 56 | mime-types (1.25) 57 | minitest (4.7.5) 58 | multi_json (1.7.9) 59 | polyglot (0.3.3) 60 | rack (1.5.2) 61 | rack-test (0.6.2) 62 | rack (>= 1.0) 63 | rails (4.0.0) 64 | actionmailer (= 4.0.0) 65 | actionpack (= 4.0.0) 66 | activerecord (= 4.0.0) 67 | activesupport (= 4.0.0) 68 | bundler (>= 1.3.0, < 2.0) 69 | railties (= 4.0.0) 70 | sprockets-rails (~> 2.0.0) 71 | railties (4.0.0) 72 | actionpack (= 4.0.0) 73 | activesupport (= 4.0.0) 74 | rake (>= 0.8.7) 75 | thor (>= 0.18.1, < 2.0) 76 | rake (10.1.0) 77 | request_store (1.0.5) 78 | rest-client (1.6.7) 79 | mime-types (>= 1.16) 80 | rspec (2.14.1) 81 | rspec-core (~> 2.14.0) 82 | rspec-expectations (~> 2.14.0) 83 | rspec-mocks (~> 2.14.0) 84 | rspec-core (2.14.5) 85 | rspec-expectations (2.14.2) 86 | diff-lcs (>= 1.1.3, < 2.0) 87 | rspec-mocks (2.14.3) 88 | rspec-rails (2.14.0) 89 | actionpack (>= 3.0) 90 | activesupport (>= 3.0) 91 | railties (>= 3.0) 92 | rspec-core (~> 2.14.0) 93 | rspec-expectations (~> 2.14.0) 94 | rspec-mocks (~> 2.14.0) 95 | simplecov (0.7.1) 96 | multi_json (~> 1.0) 97 | simplecov-html (~> 0.7.1) 98 | simplecov-html (0.7.1) 99 | sprockets (2.10.0) 100 | hike (~> 1.2) 101 | multi_json (~> 1.0) 102 | rack (~> 1.0) 103 | tilt (~> 1.1, != 1.3.0) 104 | sprockets-rails (2.0.0) 105 | actionpack (>= 3.0) 106 | activesupport (>= 3.0) 107 | sprockets (~> 2.8) 108 | thor (0.18.1) 109 | thread_safe (0.1.2) 110 | atomic 111 | tilt (1.4.1) 112 | treetop (1.4.15) 113 | polyglot 114 | polyglot (>= 0.3.1) 115 | tzinfo (0.3.37) 116 | 117 | PLATFORMS 118 | ruby 119 | 120 | DEPENDENCIES 121 | activesupport (>= 3.2) 122 | coveralls 123 | decent_decoration! 124 | draper (>= 1.0.0) 125 | rails (>= 3.2) 126 | rspec (~> 2.13) 127 | rspec-rails (~> 2.13) 128 | --------------------------------------------------------------------------------