bird_on_it 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +180 -0
 - data/lib/bird_on_it.rb +1 -2
 - data/lib/bird_on_it/decorator.rb +2 -0
 - data/lib/bird_on_it/version.rb +1 -1
 - data/test/bird_on_it_test.rb +28 -24
 - data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
 - data/test/dummy/app/controllers/tote_bags_controller.rb +62 -0
 - data/test/dummy/app/decorators/tote_bag_decorator.rb +23 -0
 - data/test/dummy/app/models/tote_bag.rb +5 -0
 - data/test/dummy/app/views/tote_bags/_form.html.erb +29 -0
 - data/test/dummy/app/views/tote_bags/edit.html.erb +6 -0
 - data/test/dummy/app/views/tote_bags/index.html.erb +31 -0
 - data/test/dummy/app/views/tote_bags/new.html.erb +5 -0
 - data/test/dummy/app/views/tote_bags/show.html.erb +20 -0
 - data/test/dummy/config/routes.rb +2 -0
 - data/test/dummy/db/development.sqlite3 +0 -0
 - data/test/dummy/db/migrate/20140314082207_create_tote_bags.rb +11 -0
 - data/test/dummy/db/schema.rb +24 -0
 - data/test/dummy/db/test.sqlite3 +0 -0
 - data/test/dummy/log/development.log +2477 -0
 - data/test/dummy/log/test.log +41 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/371bf96e99717688ed7313a0c53f4212 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/510da110ae528e2d22533be39ff696c5 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/580936cd6180b0b516e323ab3b9290bc +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/6fc757c2c8329244ca95d6909865bbc2 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/a77bf3dfc15bd59697d7d51fa6a8ebaa +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/ab3c84b0c7e5ccef7125dd305453cb65 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/c530934da9c9116acfdee38204d3cf73 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/ce526a9f65d6aa96f21611970cabe56c +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
 - data/test/dummy/tmp/cache/assets/development/sprockets/fa809407dd24d48afa01dc34b11c60b6 +0 -0
 - metadata +57 -7
 - data/README.rdoc +0 -3
 - data/test/dummy/app/decorators/canvas_bag_decorator.rb +0 -7
 - data/test/dummy/app/models/canvas_bag.rb +0 -7
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 52177a68952ac06a60c8fcfebd8b6b93b5d3bc14
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 5c5b3cc9e324e96b571dc5096e24c3f57dfb443e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 3cf19d242f8313349af3ae73ad56fe4ec8be6f3dccef05ce885808b4e7c54f303f3d9572bc29d9222e93aebc75c03ff9e88604dfd3d10d248b6f658c9d91b17b
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: be11ec856d3b5d96e7df336733fe4ecf35b782512ec5ae9887c1303b2ee886c4b4a83c1556f6138af670f8429d2355137a439ce6b433ac763b4e4238f443e81b
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,180 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Bird On It: Simple decorators for your Rails models
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Model need decorating in your Rails view? Put a bird on it!
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## What is Bird On It?
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            _Bird On It_ is a simple way to decorate models in your Rails application.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Decorators allow you to move view- and presentation-related logic out of your active record models and view helpers and into decorator classes. Doing this cleans up your view code and reduces the number of responsibilities your active record objects have.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Here's how it works. Let's say you have a ToteBag model, with colour, size and straps attributes. In your view, you want to describe whether or not the bag has straps. You also want to add some css classes, depending on what properties the bag has. You put the first of these methods on the model, and the second in a helper, like so:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 14 
     | 
    
         
            +
            # app/models/tote_bag.rb
         
     | 
| 
      
 15 
     | 
    
         
            +
            class ToteBag < ActiveRecord::Base
         
     | 
| 
      
 16 
     | 
    
         
            +
              def straps_description
         
     | 
| 
      
 17 
     | 
    
         
            +
                if straps?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  'This bag has straps'
         
     | 
| 
      
 19 
     | 
    
         
            +
                else
         
     | 
| 
      
 20 
     | 
    
         
            +
                  'This bag does not have straps'
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
            ```
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 27 
     | 
    
         
            +
            # app/helpers/tote_bags_helper.rb
         
     | 
| 
      
 28 
     | 
    
         
            +
            module ToteBagHelper
         
     | 
| 
      
 29 
     | 
    
         
            +
              def tote_bag_css_classes(tote_bag)
         
     | 
| 
      
 30 
     | 
    
         
            +
                tote_bag_css_classes = %w{tote-bag}
         
     | 
| 
      
 31 
     | 
    
         
            +
                tote_bag_css_classes << 'straps' if tote_bag.straps?
         
     | 
| 
      
 32 
     | 
    
         
            +
                tote_bag_css_classes.join(' ')
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
            ```
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            In your view, you would use both the helper and model:
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 40 
     | 
    
         
            +
            <div class="<%= tote_bag_css_classes(@tote_bag) %>">
         
     | 
| 
      
 41 
     | 
    
         
            +
              <h2>Straps:</h2>
         
     | 
| 
      
 42 
     | 
    
         
            +
              <p><%= @tote_bag.straps_description %></p>
         
     | 
| 
      
 43 
     | 
    
         
            +
            </div>
         
     | 
| 
      
 44 
     | 
    
         
            +
            ```
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Instead of the above, however, using a tote bag decorator allows both these methods to exist in the one place. The decorator sends any method that it doesn't itself respond to the decorated object. Using _Bird On It_:
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 49 
     | 
    
         
            +
            # app/models/tote_bag.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            class ToteBag < ActiveRecord::Base
         
     | 
| 
      
 51 
     | 
    
         
            +
              include BirdOnIt
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
            ```
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 56 
     | 
    
         
            +
            # app/decorators/tote_bag_decorator.rb
         
     | 
| 
      
 57 
     | 
    
         
            +
            class ToteBagDecorator
         
     | 
| 
      
 58 
     | 
    
         
            +
              include BirdOnIt::Decorator
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def straps_description
         
     | 
| 
      
 61 
     | 
    
         
            +
                if object.straps?
         
     | 
| 
      
 62 
     | 
    
         
            +
                  'This bag has straps'
         
     | 
| 
      
 63 
     | 
    
         
            +
                else
         
     | 
| 
      
 64 
     | 
    
         
            +
                  'This bag does not have straps'
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def css_classes
         
     | 
| 
      
 69 
     | 
    
         
            +
                css_classes = %w{tote-bag}
         
     | 
| 
      
 70 
     | 
    
         
            +
                css_classes << 'straps' if object.straps?
         
     | 
| 
      
 71 
     | 
    
         
            +
                css_classes.join(' ')
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
      
 74 
     | 
    
         
            +
            ```
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            In your view:
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 79 
     | 
    
         
            +
            <div class="<%= @tote_bag.css_classes %>">
         
     | 
| 
      
 80 
     | 
    
         
            +
              <h2>Straps:</h2>
         
     | 
| 
      
 81 
     | 
    
         
            +
              <p><%= @tote_bag.straps_description %></p>
         
     | 
| 
      
 82 
     | 
    
         
            +
            </div>
         
     | 
| 
      
 83 
     | 
    
         
            +
            ```
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            Now your view-related code can reside in the decorator, eliminating the need for helper methods and giving your tote bag class one less responsibility.
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            Add _Bird On It_ to your Gemfile
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 92 
     | 
    
         
            +
              gem 'bird_on_it'
         
     | 
| 
      
 93 
     | 
    
         
            +
            ```
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            Run `bundle install`.
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            ### Model
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            To decorate a model, first include _Bird On It_:
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 104 
     | 
    
         
            +
            # app/models/post.rb
         
     | 
| 
      
 105 
     | 
    
         
            +
            class Post < ActiveRecord::Base
         
     | 
| 
      
 106 
     | 
    
         
            +
              include BirdOnIt
         
     | 
| 
      
 107 
     | 
    
         
            +
            end
         
     | 
| 
      
 108 
     | 
    
         
            +
            ```
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            Then create a decorator either in `app/views/decorators` or `app/models` with the name matching your model and include `BirdOnIt::Decorator`.
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 113 
     | 
    
         
            +
            # app/decorators/post_decorator.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            class PostDecorator < ActiveRecord::Base
         
     | 
| 
      
 115 
     | 
    
         
            +
              include BirdOnIt::Decorator
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
              def display_title
         
     | 
| 
      
 118 
     | 
    
         
            +
                object.title.humanize
         
     | 
| 
      
 119 
     | 
    
         
            +
              end
         
     | 
| 
      
 120 
     | 
    
         
            +
            end
         
     | 
| 
      
 121 
     | 
    
         
            +
            ```
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            In the decorator, your decorated object is available via the `object` variable. If you prefer, you can also access it simply by calling methods to which your decorator does not respond:
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 126 
     | 
    
         
            +
            def display_title
         
     | 
| 
      
 127 
     | 
    
         
            +
              title.humanize
         
     | 
| 
      
 128 
     | 
    
         
            +
            end
         
     | 
| 
      
 129 
     | 
    
         
            +
            ```
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            ### Controller
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            _Bird On It_ adds a `decorate` method you can call on your objects in your controller before they are passed to the view.
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 136 
     | 
    
         
            +
            # app/controllers/posts_controller.rb
         
     | 
| 
      
 137 
     | 
    
         
            +
            def show
         
     | 
| 
      
 138 
     | 
    
         
            +
              @post = Post.find(params[:id]).decorate
         
     | 
| 
      
 139 
     | 
    
         
            +
            end
         
     | 
| 
      
 140 
     | 
    
         
            +
            ```
         
     | 
| 
      
 141 
     | 
    
         
            +
            There is also a `decorate_collection` class method for decorating collections.
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 144 
     | 
    
         
            +
            # app/controllers/posts_controller.rb
         
     | 
| 
      
 145 
     | 
    
         
            +
            def index
         
     | 
| 
      
 146 
     | 
    
         
            +
              @posts = Post.decorate_collection(Post.all)
         
     | 
| 
      
 147 
     | 
    
         
            +
            end
         
     | 
| 
      
 148 
     | 
    
         
            +
            ```
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            ### View
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            Use your decorated objects in the view as usual.
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 155 
     | 
    
         
            +
            <div class="post">
         
     | 
| 
      
 156 
     | 
    
         
            +
              <h1><%= @post.display_title %></h2>
         
     | 
| 
      
 157 
     | 
    
         
            +
              <p><%= @post.body %></p>
         
     | 
| 
      
 158 
     | 
    
         
            +
            </div>
         
     | 
| 
      
 159 
     | 
    
         
            +
            ```
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            Some Rails helpers, such as the edit_path helper, do not work well with decorated objects. If you encounter one of these, you can work around this by passing the helper the decorated object, instead of the decorator. For example:
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 164 
     | 
    
         
            +
            <%= link_to 'Edit', edit_post_path(@post.object) %>
         
     | 
| 
      
 165 
     | 
    
         
            +
            ```
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            Other features, such as linking to the show page, or using the object with `form_for`, should continue to work as usual.
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 170 
     | 
    
         
            +
            <%= link_to 'Show', @post %>
         
     | 
| 
      
 171 
     | 
    
         
            +
            ```
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 174 
     | 
    
         
            +
            <%= form_for(@post) do |f| %>
         
     | 
| 
      
 175 
     | 
    
         
            +
              <%= f.text_field :material %>
         
     | 
| 
      
 176 
     | 
    
         
            +
              <%= f.submit %>
         
     | 
| 
      
 177 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 178 
     | 
    
         
            +
            ```
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            This project uses MIT-LICENSE.
         
     | 
    
        data/lib/bird_on_it.rb
    CHANGED
    
    | 
         @@ -11,8 +11,7 @@ module BirdOnIt 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
              module ClassMethods
         
     | 
| 
       13 
13 
     | 
    
         
             
                def decorate_collection(collection)
         
     | 
| 
       14 
     | 
    
         
            -
                  collection  
     | 
| 
       15 
     | 
    
         
            -
                  collection.map { |item| decorator_class.new(item) }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  Array(collection).map { |item| decorator_class.new(item) }
         
     | 
| 
       16 
15 
     | 
    
         
             
                end
         
     | 
| 
       17 
16 
     | 
    
         | 
| 
       18 
17 
     | 
    
         
             
                def decorator_class
         
     | 
    
        data/lib/bird_on_it/decorator.rb
    CHANGED
    
    
    
        data/lib/bird_on_it/version.rb
    CHANGED
    
    
    
        data/test/bird_on_it_test.rb
    CHANGED
    
    | 
         @@ -1,56 +1,60 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'test_helper'
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            describe BirdOnIt do
         
     | 
| 
       4 
     | 
    
         
            -
              class  
     | 
| 
      
 4 
     | 
    
         
            +
              class ToteBag
         
     | 
| 
       5 
5 
     | 
    
         
             
                include BirdOnIt
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                def  
     | 
| 
       8 
     | 
    
         
            -
                  ' 
     | 
| 
      
 7 
     | 
    
         
            +
                def color
         
     | 
| 
      
 8 
     | 
    
         
            +
                  'red'
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
10 
     | 
    
         
             
              end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              class  
     | 
| 
      
 12 
     | 
    
         
            +
              class ToteBagDecorator
         
     | 
| 
       13 
13 
     | 
    
         
             
                include BirdOnIt::Decorator
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                def  
     | 
| 
       16 
     | 
    
         
            -
                   
     | 
| 
      
 15 
     | 
    
         
            +
                def color_description
         
     | 
| 
      
 16 
     | 
    
         
            +
                  if object.color
         
     | 
| 
      
 17 
     | 
    
         
            +
                    "This bag is #{color}"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  else
         
     | 
| 
      
 19 
     | 
    
         
            +
                    "Unknown color"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
       17 
21 
     | 
    
         
             
                end
         
     | 
| 
       18 
22 
     | 
    
         
             
              end
         
     | 
| 
       19 
23 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
              let(: 
     | 
| 
       21 
     | 
    
         
            -
              let(: 
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
              describe "when included" do
         
     | 
| 
       24 
     | 
    
         
            -
                it "adds a class method #decorator_class that returns the decorator class" do
         
     | 
| 
       25 
     | 
    
         
            -
                  Decoratable.decorator_class.must_equal DecoratableDecorator
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              let(:tote_bag)           { ToteBag.new }
         
     | 
| 
      
 25 
     | 
    
         
            +
              let(:tote_bag_decorator) { tote_bag.decorate }
         
     | 
| 
       27 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
              describe "when BirdOnIt is included" do
         
     | 
| 
       28 
28 
     | 
    
         
             
                it "adds a method #decorate that returns a decorator" do
         
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
      
 29 
     | 
    
         
            +
                  tote_bag.decorate.class.must_equal ToteBagDecorator
         
     | 
| 
       30 
30 
     | 
    
         
             
                end
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
                it "adds a class method #decorate_collection that decorates a collection" do
         
     | 
| 
       33 
     | 
    
         
            -
                  collection =  
     | 
| 
       34 
     | 
    
         
            -
                  collection.map(&:class).must_equal [ 
     | 
| 
      
 33 
     | 
    
         
            +
                  collection = ToteBag.decorate_collection [ToteBag.new, ToteBag.new]
         
     | 
| 
      
 34 
     | 
    
         
            +
                  collection.map(&:class).must_equal [ToteBagDecorator, ToteBagDecorator]
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                it "adds a class method #decorator_class that returns the decorator class" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  ToteBag.decorator_class.must_equal ToteBagDecorator
         
     | 
| 
       35 
39 
     | 
    
         
             
                end
         
     | 
| 
       36 
40 
     | 
    
         
             
              end
         
     | 
| 
       37 
41 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
              describe  
     | 
| 
      
 42 
     | 
    
         
            +
              describe ToteBagDecorator do
         
     | 
| 
       39 
43 
     | 
    
         
             
                it "responds to its own instance methods" do
         
     | 
| 
       40 
     | 
    
         
            -
                   
     | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
      
 44 
     | 
    
         
            +
                  tote_bag_decorator.respond_to?(:color_description).must_equal true
         
     | 
| 
      
 45 
     | 
    
         
            +
                  tote_bag_decorator.color_description.must_equal 'This bag is red'
         
     | 
| 
       42 
46 
     | 
    
         
             
                end
         
     | 
| 
       43 
47 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                it " 
     | 
| 
       45 
     | 
    
         
            -
                   
     | 
| 
      
 48 
     | 
    
         
            +
                it "sends missing methods to its decorated object" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  tote_bag_decorator.color.must_equal 'red'
         
     | 
| 
       46 
50 
     | 
    
         
             
                end
         
     | 
| 
       47 
51 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                it " 
     | 
| 
       49 
     | 
    
         
            -
                   
     | 
| 
      
 52 
     | 
    
         
            +
                it "responds to the methods of the decorated object" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                  tote_bag_decorator.respond_to?(:color).must_equal true
         
     | 
| 
       50 
54 
     | 
    
         
             
                end
         
     | 
| 
       51 
55 
     | 
    
         | 
| 
       52 
56 
     | 
    
         
             
                it "has an object attribute that is the decorated object" do
         
     | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
      
 57 
     | 
    
         
            +
                  tote_bag_decorator.object.must_equal tote_bag
         
     | 
| 
       54 
58 
     | 
    
         
             
                end
         
     | 
| 
       55 
59 
     | 
    
         
             
              end
         
     | 
| 
       56 
60 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,56 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            body { background-color: #fff; color: #333; }
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            body, p, ol, ul, td {
         
     | 
| 
      
 4 
     | 
    
         
            +
              font-family: verdana, arial, helvetica, sans-serif;
         
     | 
| 
      
 5 
     | 
    
         
            +
              font-size:   13px;
         
     | 
| 
      
 6 
     | 
    
         
            +
              line-height: 18px;
         
     | 
| 
      
 7 
     | 
    
         
            +
            }
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            pre {
         
     | 
| 
      
 10 
     | 
    
         
            +
              background-color: #eee;
         
     | 
| 
      
 11 
     | 
    
         
            +
              padding: 10px;
         
     | 
| 
      
 12 
     | 
    
         
            +
              font-size: 11px;
         
     | 
| 
      
 13 
     | 
    
         
            +
            }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            a { color: #000; }
         
     | 
| 
      
 16 
     | 
    
         
            +
            a:visited { color: #666; }
         
     | 
| 
      
 17 
     | 
    
         
            +
            a:hover { color: #fff; background-color:#000; }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            div.field, div.actions {
         
     | 
| 
      
 20 
     | 
    
         
            +
              margin-bottom: 10px;
         
     | 
| 
      
 21 
     | 
    
         
            +
            }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            #notice {
         
     | 
| 
      
 24 
     | 
    
         
            +
              color: green;
         
     | 
| 
      
 25 
     | 
    
         
            +
            }
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            .field_with_errors {
         
     | 
| 
      
 28 
     | 
    
         
            +
              padding: 2px;
         
     | 
| 
      
 29 
     | 
    
         
            +
              background-color: red;
         
     | 
| 
      
 30 
     | 
    
         
            +
              display: table;
         
     | 
| 
      
 31 
     | 
    
         
            +
            }
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            #error_explanation {
         
     | 
| 
      
 34 
     | 
    
         
            +
              width: 450px;
         
     | 
| 
      
 35 
     | 
    
         
            +
              border: 2px solid red;
         
     | 
| 
      
 36 
     | 
    
         
            +
              padding: 7px;
         
     | 
| 
      
 37 
     | 
    
         
            +
              padding-bottom: 0;
         
     | 
| 
      
 38 
     | 
    
         
            +
              margin-bottom: 20px;
         
     | 
| 
      
 39 
     | 
    
         
            +
              background-color: #f0f0f0;
         
     | 
| 
      
 40 
     | 
    
         
            +
            }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            #error_explanation h2 {
         
     | 
| 
      
 43 
     | 
    
         
            +
              text-align: left;
         
     | 
| 
      
 44 
     | 
    
         
            +
              font-weight: bold;
         
     | 
| 
      
 45 
     | 
    
         
            +
              padding: 5px 5px 5px 15px;
         
     | 
| 
      
 46 
     | 
    
         
            +
              font-size: 12px;
         
     | 
| 
      
 47 
     | 
    
         
            +
              margin: -7px;
         
     | 
| 
      
 48 
     | 
    
         
            +
              margin-bottom: 0px;
         
     | 
| 
      
 49 
     | 
    
         
            +
              background-color: #c00;
         
     | 
| 
      
 50 
     | 
    
         
            +
              color: #fff;
         
     | 
| 
      
 51 
     | 
    
         
            +
            }
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            #error_explanation ul li {
         
     | 
| 
      
 54 
     | 
    
         
            +
              font-size: 12px;
         
     | 
| 
      
 55 
     | 
    
         
            +
              list-style: square;
         
     | 
| 
      
 56 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,62 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class ToteBagsController < ApplicationController
         
     | 
| 
      
 2 
     | 
    
         
            +
              respond_to :html
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              # GET /tote_bags
         
     | 
| 
      
 5 
     | 
    
         
            +
              def index
         
     | 
| 
      
 6 
     | 
    
         
            +
                @tote_bags = ToteBag.decorate_collection(ToteBag.all)
         
     | 
| 
      
 7 
     | 
    
         
            +
                respond_with @tote_bags
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              # GET /tote_bags/1
         
     | 
| 
      
 11 
     | 
    
         
            +
              def show
         
     | 
| 
      
 12 
     | 
    
         
            +
                @tote_bag = ToteBag.find(params[:id]).decorate
         
     | 
| 
      
 13 
     | 
    
         
            +
                respond_with @tote_bag
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              # GET /tote_bags/new
         
     | 
| 
      
 17 
     | 
    
         
            +
              def new
         
     | 
| 
      
 18 
     | 
    
         
            +
                @tote_bag = ToteBag.new
         
     | 
| 
      
 19 
     | 
    
         
            +
                respond_with @tote_bag
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              # GET /tote_bags/1/edit
         
     | 
| 
      
 23 
     | 
    
         
            +
              def edit
         
     | 
| 
      
 24 
     | 
    
         
            +
                @tote_bag = ToteBag.find(params[:id]).decorate
         
     | 
| 
      
 25 
     | 
    
         
            +
                respond_with @tote_bag
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              # POST /tote_bags
         
     | 
| 
      
 29 
     | 
    
         
            +
              def create
         
     | 
| 
      
 30 
     | 
    
         
            +
                @tote_bag = ToteBag.new(tote_bag_params)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                if @tote_bag.save
         
     | 
| 
      
 33 
     | 
    
         
            +
                  redirect_to @tote_bag, notice: 'Tote bag was successfully created.'
         
     | 
| 
      
 34 
     | 
    
         
            +
                else
         
     | 
| 
      
 35 
     | 
    
         
            +
                  render :new
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              # PATCH/PUT /tote_bags/1
         
     | 
| 
      
 40 
     | 
    
         
            +
              def update
         
     | 
| 
      
 41 
     | 
    
         
            +
                @tote_bag = ToteBag.find(params[:id])
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                if @tote_bag.update(tote_bag_params)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  redirect_to @tote_bag, notice: 'Tote bag was successfully updated.'
         
     | 
| 
      
 45 
     | 
    
         
            +
                else
         
     | 
| 
      
 46 
     | 
    
         
            +
                  render :edit
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              # DELETE /tote_bags/1
         
     | 
| 
      
 51 
     | 
    
         
            +
              def destroy
         
     | 
| 
      
 52 
     | 
    
         
            +
                @tote_bag = ToteBag.find(params[:id])
         
     | 
| 
      
 53 
     | 
    
         
            +
                @tote_bag.destroy
         
     | 
| 
      
 54 
     | 
    
         
            +
                redirect_to tote_bags_url, notice: 'Tote bag was successfully destroyed.'
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              private
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              def tote_bag_params
         
     | 
| 
      
 60 
     | 
    
         
            +
                params.require(:tote_bag).permit(:colour, :material, :straps)
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class ToteBagDecorator
         
     | 
| 
      
 2 
     | 
    
         
            +
              include BirdOnIt::Decorator
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def css_classes
         
     | 
| 
      
 5 
     | 
    
         
            +
                css_classes = %w{tote-bag}
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                css_classes << 'straps' if object.straps?
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                css_classes.join(' ')
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def colour_description
         
     | 
| 
      
 13 
     | 
    
         
            +
                object.colour.present? ? object.colour : 'Has no colour'
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def material_description
         
     | 
| 
      
 17 
     | 
    
         
            +
                object.material.present? ? object.material : 'Unknown material'
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def straps_description
         
     | 
| 
      
 21 
     | 
    
         
            +
                object.straps? ? 'Has straps' : 'Strapless'
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     |