Agile Web Development with Rails, Edition 4 
      11.2 Iteration F2: Creating an AJAX-Based Cart 
      10.4 Playtime 
    
    
      11.1 Iteration F1: Moving the Cart 
     
    Refactor the cart view into partials, and reference the result from the layout.
    Create a "partial" view, for just one line item
    edit app/views/line_items/_line_item.html.erb <tr> 
      <td><%= line_item.quantity %>×</td> 
      <td><%= line_item.product.title %></td> 
      <td class="item_price"><%= number_to_currency(line_item.total_price) %></td> 
    </tr> 
    Replace that portion of the view with a callout to the partial
    edit app/views/carts/show.html.erb <p id="notice"><%= notice %></p> 
      
    <h2>Your Cart</h2> 
    <table> 
      <%= render(@cart.line_items) %> 
      
      <tr class="total_line"> 
        <td colspan="2">Total</td> 
        <td class="total_cell"><%= number_to_currency(@cart.total_price) %></td> 
      </tr> 
      
    </table> 
      
    <%= button_to 'Empty cart', @cart, method: :delete, 
        data: { confirm: 'Are you sure?' } %> 
    Make a copy as a partial for the cart controller
    cp app/views/carts/show.html.erb app/views/carts/_cart.html.erb Modify the copy to reference the (sub)partial and take input from @cart
    edit app/views/carts/_cart.html.erb <h2>Your Cart</h2> 
    <table> 
      <%= render(cart.line_items) %> 
      
      <tr class="total_line"> 
        <td colspan="2">Total</td> 
        <td class="total_cell"><%= number_to_currency(cart.total_price) %></td> 
      </tr> 
      
    </table> 
      
    <%= button_to 'Empty cart', cart, method: :delete, 
        data: { confirm: 'Are you sure?' } %> 
    Keep things DRY
    edit app/views/carts/show.html.erb <p id="notice"><%= notice %></p> 
      
    <%= render @cart %> 
    Reference the partial from the layout.
    edit app/views/layouts/application.html.erb <!DOCTYPE html> 
    <html> 
      <head> 
        <title>Pragprog Books Online Store</title> 
        <%= csrf_meta_tags %> 
      
        <%= csrf_meta_tags %> 
      
        <%= stylesheet_link_tag    'application', media: 'all', 
        'data-turbolinks-track': 'reload' %> 
        <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 
      </head> 
      
      <body class="<%= controller.controller_name %>"> 
        <div id="banner"> 
          <%= image_tag 'logo.svg', alt: 'The Pragmatic Bookshelf' %> 
          <span class="title"><%= @page_title %></span> 
        </div> 
        <div id="columns"> 
          <div id="side"> 
            <div id="cart"> 
              <%= render @cart %> 
            </div> 
      
            <ul> 
              <li><a href="http://www....">Home</a></li> 
              <li><a href="http://www..../faq">Questions</a></li> 
              <li><a href="http://www..../news">News</a></li> 
              <li><a href="http://www..../contact">Contact</a></li> 
            </ul> 
          </div> 
          <div id="main"> 
            <%= yield %> 
          </div> 
        </div> 
      </body> 
    </html> 
    Insert a call in the controller to find the cart
    edit app/controllers/store_controller.rb class StoreController < ApplicationController 
      include CurrentCart 
      before_action :set_cart 
      def index 
        @products = Product.order(:title) 
      end 
    end 
    Add a small bit of style.
    edit app/assets/stylesheets/carts.scss // Place all the styles related to the Carts controller here. 
    // They will automatically be included in application.css. 
    // You can use Sass (SCSS) here: http://sass-lang.com/ 
      
    .carts, #side #cart { 
      .item_price, .total_line { 
        text-align: right; 
      } 
      
      .total_line .total_cell { 
        font-weight: bold; 
        border-top: 1px solid #595; 
      } 
    } 
    edit app/assets/stylesheets/application.css.scss   #side { 
        padding: 1em 2em; 
        background: #141; 
      
        form, div { 
          display: inline; 
        }   
      
        input { 
          font-size: small; 
        } 
      
        #cart { 
          font-size: smaller; 
          color:     white; 
      
          table { 
            border-top:    1px dotted #595; 
            border-bottom: 1px dotted #595; 
            margin-bottom: 10px; 
          } 
        } 
      
        ul { 
          padding: 0; 
      
          li { 
            list-style: none; 
      
            a { 
              color: #bfb; 
              font-size: small; 
            } 
          } 
        } 
      } 
    Change the redirect to be back to the store.
    edit app/controllers/line_items_controller.rb   def create 
        product = Product.find(params[:product_id]) 
        @line_item = @cart.add_product(product) 
      
        respond_to do |format| 
          if @line_item.save 
            format.html { redirect_to store_index_url } 
            format.json { render :show, 
              status: :created, location: @line_item } 
          else 
            format.html { render :new } 
            format.json { render json: @line_item.errors, 
              status: :unprocessable_entity } 
          end 
        end 
      end 
    Purchase another product.
    get / 
       
    
      
        
          Your Cart 
  
  2× 
  Rails, Angular, Postgres, and Bootstrap 
  $90.00 
 
  1× 
  Seven Mobile Apps in Seven Weeks 
  $26.00 
 
  
    Total 
    $116.00 
   
         
        
       
      
        
Your Pragmatic Catalog 
      
        Rails, Angular, Postgres, and Bootstrap 
        
      Powerful, Effective, and Efficient Full-Stack Web Development 
      As a Rails developer, you care about user experience and performance,
      but you also want simple and maintainable code. Achieve all that by
      embracing the full stack of web development, from styling with
      Bootstrap, building an interactive user interface with AngularJS, to
      storing data quickly and reliably in PostgreSQL. Take a holistic view of
      full-stack development to create usable, high-performing applications,
      and learn to use these technologies effectively in a Ruby on Rails
      environment.
      
        
          $45.00 
          
        
       
      
        Ruby Performance Optimization 
        
      Why Ruby Is Slow, and How to Fix It  
      You don’t have to accept slow Ruby or Rails performance. In this
      comprehensive guide to Ruby optimization, you’ll learn how to write
      faster Ruby code—but that’s just the beginning. See exactly what makes
      Ruby and Rails code slow, and how to fix it. Alex Dymo will guide you
      through perils of memory and CPU optimization, profiling, measuring,
      performance testing, garbage collection, and tuning. You’ll find that
      all those “hard” things aren’t so difficult after all, and your code
      will run orders of magnitude faster.
      
        
          $46.00 
          
        
       
      
        Seven Mobile Apps in Seven Weeks 
        
      Native Apps, Multiple Platforms 
      Answer the question “Can we build this for ALL the devices?” with a
      resounding YES. This book will help you get there with a real-world
      introduction to seven platforms, whether you’re new to mobile or an
      experienced developer needing to expand your options. Plus, you’ll find
      out which cross-platform solution makes the most sense for your needs.
      
        
          $26.00 
          
        
       
       
     
       
    
    post /line_items?product_id=3 
You are being 
redirected .    
    get http://localhost:3000/store/index 
       
    
      
        
          Your Cart 
  
  2× 
  Rails, Angular, Postgres, and Bootstrap 
  $90.00 
 
  2× 
  Seven Mobile Apps in Seven Weeks 
  $52.00 
 
  
    Total 
    $142.00 
   
         
        
       
      
        
Your Pragmatic Catalog 
      
        Rails, Angular, Postgres, and Bootstrap 
        
      Powerful, Effective, and Efficient Full-Stack Web Development 
      As a Rails developer, you care about user experience and performance,
      but you also want simple and maintainable code. Achieve all that by
      embracing the full stack of web development, from styling with
      Bootstrap, building an interactive user interface with AngularJS, to
      storing data quickly and reliably in PostgreSQL. Take a holistic view of
      full-stack development to create usable, high-performing applications,
      and learn to use these technologies effectively in a Ruby on Rails
      environment.
      
        
          $45.00 
          
        
       
      
        Ruby Performance Optimization 
        
      Why Ruby Is Slow, and How to Fix It  
      You don’t have to accept slow Ruby or Rails performance. In this
      comprehensive guide to Ruby optimization, you’ll learn how to write
      faster Ruby code—but that’s just the beginning. See exactly what makes
      Ruby and Rails code slow, and how to fix it. Alex Dymo will guide you
      through perils of memory and CPU optimization, profiling, measuring,
      performance testing, garbage collection, and tuning. You’ll find that
      all those “hard” things aren’t so difficult after all, and your code
      will run orders of magnitude faster.
      
        
          $46.00 
          
        
       
      
        Seven Mobile Apps in Seven Weeks 
        
      Native Apps, Multiple Platforms 
      Answer the question “Can we build this for ALL the devices?” with a
      resounding YES. This book will help you get there with a real-world
      introduction to seven platforms, whether you’re new to mobile or an
      experienced developer needing to expand your options. Plus, you’ll find
      out which cross-platform solution makes the most sense for your needs.
      
        
          $26.00 
          
        
       
       
     
       
    
    Run tests... oops.
    rake test Run options: --seed 45754 
      
    # Running: 
      
    .....E.EEF..EE....EEEE........ 
      
    Finished in 0.507751s, 59.0841 runs/s, 124.0766 assertions/s. 
      
      1) Error: 
    CartsControllerTest#test_should_get_index: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/carts_controller_test.rb:9:in `block in <class:CartsControllerTest>' 
      
      
      2) Error: 
    LineItemsControllerTest#test_should_get_index: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/line_items_controller_test.rb:9:in `block in <class:LineItemsControllerTest>' 
      
      
      3) Error: 
    LineItemsControllerTest#test_should_show_line_item: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/line_items_controller_test.rb:34:in `block in <class:LineItemsControllerTest>' 
      
      
      4) Failure: 
    LineItemsControllerTest#test_should_create_line_item [/home/rubys/git/awdwr/edition4/work-226-42/depot/test/controllers/line_items_controller_test.rb:28]: 
    Expected response to be a redirect to <http://test.host/carts/980190963> but was a redirect to <http://test.host/store/index>. 
    Expected "http://test.host/carts/980190963" to be === "http://test.host/store/index". 
      
      
      5) Error: 
    LineItemsControllerTest#test_should_get_edit: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/line_items_controller_test.rb:39:in `block in <class:LineItemsControllerTest>' 
      
      
      6) Error: 
    LineItemsControllerTest#test_should_get_new: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/line_items_controller_test.rb:15:in `block in <class:LineItemsControllerTest>' 
      
      
      7) Error: 
    ProductsControllerTest#test_should_get_index: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/products_controller_test.rb:18:in `block in <class:ProductsControllerTest>' 
      
      
      8) Error: 
    ProductsControllerTest#test_should_get_new: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/products_controller_test.rb:24:in `block in <class:ProductsControllerTest>' 
      
      
      9) Error: 
    ProductsControllerTest#test_should_get_edit: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/products_controller_test.rb:44:in `block in <class:ProductsControllerTest>' 
      
      
     10) Error: 
    ProductsControllerTest#test_should_show_product: 
    ActionView::Template::Error: 'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path. 
        app/views/layouts/application.html.erb:25:in `_app_views_layouts_application_html_erb___3247857296546834603_42164480' 
        test/controllers/products_controller_test.rb:39:in `block in <class:ProductsControllerTest>' 
      
    30 runs, 63 assertions, 1 failures, 9 errors, 0 skips 
    Verify that the products page is indeed broken
    get /products HTTP Response Code: 500
    
  
    ArgumentError in
    Products#index
   
 
  
    Showing /home/rubys/git/awdwr/edition4/work-226-42/depot/app/views/layouts/application.html.erb  where line #25  raised:
  
  'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path.
      
        Extracted source (around line #478 ):
      
      
        
          
            
              
476 
477 
478 
479 
480 
481 
               
             
        object.to_partial_path
      else
        raise ArgumentError.new("'#{object.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.")
      end
      if @view.prefix_partial_path_with_controller_namespace
 
 
           
        
       
     
    
      
        Extracted source (around line #382 ):
      
      
        
          
            
              
380 
381 
382 
383 
384 
385 
               
             
          @path = paths.uniq.one? ? paths.first : nil
        else
          @path = partial_path
        end
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #293 ):
      
      
        
          
            
              
291 
292 
293 
294 
295 
296 
               
             
    def render(context, options, block)
      setup(context, options, block)
      identifier = (@template = find_partial) ? @template.identifier : @path
      @lookup_context.rendered_format ||= begin
 
 
           
        
       
     
    
      
        Extracted source (around line #51 ):
      
      
        
          
            
              
49 
50 
51 
52 
53 
54 
               
             
    # Direct access to partial rendering.
    def render_partial(context, options, &block) #:nodoc:
      PartialRenderer.new(@lookup_context).render(context, options, block)
    end
  end
end
 
 
           
        
       
     
    
      
        Extracted source (around line #35 ):
      
      
        
          
            
              
33 
34 
35 
36 
37 
38 
               
             
          end
        else
          view_renderer.render_partial(self, :partial => options, :locals => locals)
        end
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #25 ):
      
      
        
          
            
              
23 
24 
25 
26 
27 
28 
               
             
<!-- START_HIGHLIGHT -->
        <div id="cart">
          <%= render @cart %>
        </div>
<!-- END_HIGHLIGHT -->
 
 
           
        
       
     
    
      
        Extracted source (around line #145 ):
      
      
        
          
            
              
143 
144 
145 
146 
147 
148 
               
             
      instrument("!render_template") do
        compile!(view)
        view.send(method_name, locals, buffer, &block)
      end
    rescue => e
      handle_render_error(view, e)
 
 
           
        
       
     
    
      
        Extracted source (around line #166 ):
      
      
        
          
            
              
164 
165 
166 
167 
168 
169 
               
             
          instrumenter.instrument(name, payload) { yield payload if block_given? }
        else
          yield payload if block_given?
        end
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #333 ):
      
      
        
          
            
              
331 
332 
333 
334 
335 
336 
               
             
      def instrument(action, &block)
        payload = { virtual_path: @virtual_path, identifier: @identifier }
        ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block)
      end
  end
end
 
 
           
        
       
     
    
      
        Extracted source (around line #143 ):
      
      
        
          
            
              
141 
142 
143 
144 
145 
146 
               
             
    # consume this in production. This is only slow if it's being listened to.
    def render(view, locals, buffer=nil, &block)
      instrument("!render_template") do
        compile!(view)
        view.send(method_name, locals, buffer, &block)
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #66 ):
      
      
        
          
            
              
64 
65 
66 
67 
68 
69 
               
             
        view = @view
        view.view_flow.set(:layout, content)
        layout.render(view, locals){ |*name| view._layout_for(*name) }
      else
        content
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #52 ):
      
      
        
          
            
              
50 
51 
52 
53 
54 
55 
               
             
      view, locals = @view, locals || {}
      render_with_layout(layout_name, locals) do |layout|
        instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
          template.render(view, locals) { |*name| view._layout_for(*name) }
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #14 ):
      
      
        
          
            
              
12 
13 
14 
15 
16 
17 
               
             
      @lookup_context.rendered_format ||= (template.formats.first || formats.first)
      render_template(template, options[:layout], options[:locals])
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #46 ):
      
      
        
          
            
              
44 
45 
46 
47 
48 
49 
               
             
    # Direct accessor to template rendering.
    def render_template(context, options) #:nodoc:
      TemplateRenderer.new(@lookup_context).render(context, options)
    end
    # Direct access to partial rendering.
 
 
           
        
       
     
    
      
        Extracted source (around line #27 ):
      
      
        
          
            
              
25 
26 
27 
28 
29 
30 
               
             
        render_partial(context, options)
      else
        render_template(context, options)
      end
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #100 ):
      
      
        
          
            
              
98 
99 
100 
101 
102 
103 
               
             
        lookup_context.variants = variant if variant
        view_renderer.render(view_context, options)
      end
      # Assign the rendered format to lookup context.
 
 
           
        
       
     
    
      
        Extracted source (around line #217 ):
      
      
        
          
            
              
215 
216 
217 
218 
219 
220 
               
             
          Rack::Chunked::Body.new view_renderer.render_body(view_context, options)
        else
          super
        end
      end
  end
 
 
           
        
       
     
    
      
        Extracted source (around line #83 ):
      
      
        
          
            
              
81 
82 
83 
84 
85 
86 
               
             
    def render_to_body(options = {})
      _process_options(options)
      _render_template(options)
    end
    def rendered_format
 
 
           
        
       
     
    
      
        Extracted source (around line #32 ):
      
      
        
          
            
              
30 
31 
32 
33 
34 
35 
               
             
    def render_to_body(options = {})
      super || _render_in_priorities(options) || ' '
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #37 ):
      
      
        
          
            
              
35 
36 
37 
38 
39 
40 
               
             
    def render_to_body(options)
      _render_to_body_with_renderer(options) || super
    end
    def _render_to_body_with_renderer(options)
 
 
           
        
       
     
    
      
        Extracted source (around line #25 ):
      
      
        
          
            
              
23 
24 
25 
26 
27 
28 
               
             
    def render(*args, &block)
      options = _normalize_render(*args, &block)
      self.response_body = render_to_body(options)
      _process_format(rendered_format, options) if rendered_format
      self.response_body
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #16 ):
      
      
        
          
            
              
14 
15 
16 
17 
18 
19 
               
             
    def render(*args) #:nodoc:
      raise ::AbstractController::DoubleRenderError if self.response_body
      super
    end
    # Overwrite render_to_string because body can now be set to a rack body.
 
 
           
        
       
     
    
      
        Extracted source (around line #44 ):
      
      
        
          
            
              
42 
43 
44 
45 
46 
47 
               
             
      render_output = nil
      self.view_runtime = cleanup_view_runtime do
        Benchmark.ms { render_output = super }
      end
      render_output
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #12 ):
      
      
        
          
            
              
10 
11 
12 
13 
14 
               
             
  #   # => 0.074
  def ms
    1000 * realtime { yield }
  end
end
 
 
           
        
       
     
    
      
        Extracted source (around line #303 ):
      
      
        
          
            
              
301 
302 
303 
304 
305 
306 
               
             
  def realtime # :yield:
    r0 = Process.clock_gettime(BENCHMARK_CLOCK)
    yield
    Process.clock_gettime(BENCHMARK_CLOCK) - r0
  end
 
 
           
        
       
     
    
      
        Extracted source (around line #12 ):
      
      
        
          
            
              
10 
11 
12 
13 
14 
               
             
  #   # => 0.074
  def ms
    1000 * realtime { yield }
  end
end
 
 
           
        
       
     
    
      
        Extracted source (around line #44 ):
      
      
        
          
            
              
42 
43 
44 
45 
46 
47 
               
             
      render_output = nil
      self.view_runtime = cleanup_view_runtime do
        Benchmark.ms { render_output = super }
      end
      render_output
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #87 ):
      
      
        
          
            
              
85 
86 
87 
88 
89 
90 
               
             
    # :api: plugin
    def cleanup_view_runtime #:nodoc:
      yield
    end
    # Every time after an action is processed, this method is invoked
 
 
           
        
       
     
    
      
        Extracted source (around line #25 ):
      
      
        
          
            
              
23 
24 
25 
26 
27 
28 
               
             
          db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
          self.db_runtime = (db_runtime || 0) + db_rt_before_render
          runtime = super
          db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
          self.db_runtime += db_rt_after_render
          runtime - db_rt_after_render
 
 
           
        
       
     
    
      
        Extracted source (around line #43 ):
      
      
        
          
            
              
41 
42 
43 
44 
45 
46 
               
             
    def render(*args)
      render_output = nil
      self.view_runtime = cleanup_view_runtime do
        Benchmark.ms { render_output = super }
      end
      render_output
 
 
           
        
       
     
    
      
        Extracted source (around line #10 ):
      
      
        
          
            
              
8 
9 
10 
11 
12 
13 
               
             
    def default_render(*args)
      render(*args)
    end
    def method_for_action(action_name)
 
 
           
        
       
     
    
      
        Extracted source (around line #5 ):
      
      
        
          
            
              
3 
4 
5 
6 
7 
8 
               
             
    def send_action(method, *args)
      ret = super
      default_render unless performed?
      ret
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #198 ):
      
      
        
          
            
              
196 
197 
198 
199 
200 
201 
               
             
      # which is *not* necessarily the same as the action name.
      def process_action(method_name, *args)
        send_action(method_name, *args)
      end
      # Actually call the method associated with the action. Override
 
 
           
        
       
     
    
      
        Extracted source (around line #10 ):
      
      
        
          
            
              
8 
9 
10 
11 
12 
13 
               
             
    def process_action(*) #:nodoc:
      self.formats = request.formats.map(&:ref).compact
      super
    end
    # Check for double render errors and set the content_type after rendering.
 
 
           
        
       
     
    
      
        Extracted source (around line #20 ):
      
      
        
          
            
              
18 
19 
20 
21 
22 
23 
               
             
    def process_action(*args)
      run_callbacks(:process_action) do
        super
      end
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #117 ):
      
      
        
          
            
              
115 
116 
117 
118 
119 
120 
               
             
        def call(env)
          block = env.run_block
          env.value = !env.halted && (!block || block.call)
          env
        end
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #117 ):
      
      
        
          
            
              
115 
116 
117 
118 
119 
120 
               
             
        def call(env)
          block = env.run_block
          env.value = !env.halted && (!block || block.call)
          env
        end
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #555 ):
      
      
        
          
            
              
553 
554 
555 
556 
557 
558 
               
             
      def compile
        @callbacks || @mutex.synchronize do
          final_sequence = CallbackSequence.new { |env| Filters::ENDING.call(env) }
          @callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
            callback.apply callback_sequence
          end
 
 
           
        
       
     
    
      
        Extracted source (around line #505 ):
      
      
        
          
            
              
503 
504 
505 
506 
507 
508 
               
             
      def call(*args)
        @before.each { |b| b.call(*args) }
        value = @call.call(*args)
        @after.each { |a| a.call(*args) }
        value
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #505 ):
      
      
        
          
            
              
503 
504 
505 
506 
507 
508 
               
             
      def call(*args)
        @before.each { |b| b.call(*args) }
        value = @call.call(*args)
        @after.each { |a| a.call(*args) }
        value
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #92 ):
      
      
        
          
            
              
90 
91 
92 
93 
94 
95 
               
             
        runner = callbacks.compile
        e = Filters::Environment.new(self, false, nil, block)
        runner.call(e).value
      end
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #778 ):
      
      
        
          
            
              
776 
777 
778 
779 
780 
781 
               
             
          module_eval <<-RUBY, __FILE__, __LINE__ + 1
            def _run_#{name}_callbacks(&block)
              __run_callbacks__(_#{name}_callbacks, &block)
            end
          RUBY
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #81 ):
      
      
        
          
            
              
79 
80 
81 
82 
83 
84 
               
             
    #   end
    def run_callbacks(kind, &block)
      send "_run_#{kind}_callbacks", &block
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #19 ):
      
      
        
          
            
              
17 
18 
19 
20 
21 
22 
               
             
    # process_action callbacks around the normal behavior.
    def process_action(*args)
      run_callbacks(:process_action) do
        super
      end
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #29 ):
      
      
        
          
            
              
27 
28 
29 
30 
31 
32 
               
             
    private
      def process_action(*args)
        super
      rescue Exception => exception
        request.env['action_dispatch.show_detailed_exceptions'] ||= show_detailed_exceptions?
        rescue_with_handler(exception) || raise(exception)
 
 
           
        
       
     
    
      
        Extracted source (around line #32 ):
      
      
        
          
            
              
30 
31 
32 
33 
34 
35 
               
             
      ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
        begin
          result = super
          payload[:status] = response.status
          result
        ensure
 
 
           
        
       
     
    
      
        Extracted source (around line #164 ):
      
      
        
          
            
              
162 
163 
164 
165 
166 
167 
               
             
      def instrument(name, payload = {})
        if notifier.listening?(name)
          instrumenter.instrument(name, payload) { yield payload if block_given? }
        else
          yield payload if block_given?
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #20 ):
      
      
        
          
            
              
18 
19 
20 
21 
22 
23 
               
             
        start name, payload
        begin
          yield payload
        rescue Exception => e
          payload[:exception] = [e.class.name, e.message]
          raise e
 
 
           
        
       
     
    
      
        Extracted source (around line #164 ):
      
      
        
          
            
              
162 
163 
164 
165 
166 
167 
               
             
      def instrument(name, payload = {})
        if notifier.listening?(name)
          instrumenter.instrument(name, payload) { yield payload if block_given? }
        else
          yield payload if block_given?
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #30 ):
      
      
        
          
            
              
28 
29 
30 
31 
32 
33 
               
             
      ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
      ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
        begin
          result = super
          payload[:status] = response.status
 
 
           
        
       
     
    
      
        Extracted source (around line #250 ):
      
      
        
          
            
              
248 
249 
250 
251 
252 
253 
               
             
        request.filtered_parameters.merge! wrapped_filtered_hash
      end
      super
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #18 ):
      
      
        
          
            
              
16 
17 
18 
19 
20 
21 
               
             
        # and it won't be cleaned up by the method below.
        ActiveRecord::LogSubscriber.reset_runtime
        super
      end
      def cleanup_view_runtime
 
 
           
        
       
     
    
      
        Extracted source (around line #137 ):
      
      
        
          
            
              
135 
136 
137 
138 
139 
140 
               
             
      @_response_body = nil
      process_action(action_name, *args)
    end
    # Delegates to the class' #controller_path
 
 
           
        
       
     
    
      
        Extracted source (around line #30 ):
      
      
        
          
            
              
28 
29 
30 
31 
32 
33 
               
             
    def process(*) #:nodoc:
      old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
      super
    ensure
      I18n.config = old_config
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #196 ):
      
      
        
          
            
              
194 
195 
196 
197 
198 
199 
               
             
      @_env = request.env
      @_env['action_controller.instance'] = self
      process(name)
      to_a
    end
 
 
           
        
       
     
    
      
        Extracted source (around line #13 ):
      
      
        
          
            
              
11 
12 
13 
14 
15 
16 
               
             
    def dispatch(action, request)
      set_response!(request)
      super(action, request)
    end
    def response_body=(body)
 
 
           
        
       
     
    
      
        Extracted source (around line #237 ):
      
      
        
          
            
              
235 
236 
237 
238 
239 
240 
               
             
        end
      else
        lambda { |env| new.dispatch(name, klass.new(env)) }
      end
    end
  end
 
 
           
        
       
     
    
      
        Extracted source (around line #74 ):
      
      
        
          
            
              
72 
73 
74 
75 
76 
77 
               
             
        def dispatch(controller, action, env)
          controller.action(action).call(env)
        end
        def normalize_controller!(params)
 
 
           
        
       
     
    
      
        Extracted source (around line #74 ):
      
      
        
          
            
              
72 
73 
74 
75 
76 
77 
               
             
        def dispatch(controller, action, env)
          controller.action(action).call(env)
        end
        def normalize_controller!(params)
 
 
           
        
       
     
    
      
        Extracted source (around line #43 ):
      
      
        
          
            
              
41 
42 
43 
44 
45 
46 
               
             
          end
          dispatch(controller, params[:action], req.env)
        end
        def prepare_params!(params)
 
 
           
        
       
     
    
      
        Extracted source (around line #43 ):
      
      
        
          
            
              
41 
42 
43 
44 
45 
46 
               
             
          req.path_parameters = set_params.merge parameters
          status, headers, body = route.app.serve(req)
          if 'pass' == headers['X-Cascade']
            req.script_name     = script_name
 
 
           
        
       
     
    
      
        Extracted source (around line #30 ):
      
      
        
          
            
              
28 
29 
30 
31 
32 
33 
               
             
      def serve(req)
        find_routes(req).each do |match, parameters, route|
          set_params  = req.path_parameters
          path_info   = req.path_info
          script_name = req.script_name
 
 
           
        
       
     
    
      
        Extracted source (around line #30 ):
      
      
        
          
            
              
28 
29 
30 
31 
32 
33 
               
             
      def serve(req)
        find_routes(req).each do |match, parameters, route|
          set_params  = req.path_parameters
          path_info   = req.path_info
          script_name = req.script_name
 
 
           
        
       
     
    
      
        Extracted source (around line #817 ):
      
      
        
          
            
              
815 
816 
817 
818 
819 
820 
               
             
        req = request_class.new(env)
        req.path_info = Journey::Router::Utils.normalize_path(req.path_info)
        @router.serve(req)
      end
      def recognize_path(path, environment = {})
 
 
           
        
       
     
    
      
        Extracted source (around line #24 ):
      
      
        
          
            
              
22 
23 
24 
25 
26 
27 
               
             
    def call(env)
      status, headers, body = @app.call(env)
      if etag_status?(status) && etag_body?(body) && !skip_caching?(headers)
        original_body = body
 
 
           
        
       
     
    
      
        Extracted source (around line #25 ):
      
      
        
          
            
              
23 
24 
25 
26 
27 
28 
               
             
      case env[REQUEST_METHOD]
      when "GET", "HEAD"
        status, headers, body = @app.call(env)
        headers = Utils::HeaderHash.new(headers)
        if status == 200 && fresh?(env, headers)
          status = 304
 
 
           
        
       
     
    
      
        Extracted source (around line #13 ):
      
      
        
          
            
              
11 
12 
13 
14 
15 
16 
               
             
  def call(env)
    status, headers, body = @app.call(env)
    if env[REQUEST_METHOD] == HEAD
      [
 
 
           
        
       
     
    
      
        Extracted source (around line #27 ):
      
      
        
          
            
              
25 
26 
27 
28 
29 
30 
               
             
      end
      @app.call(env)
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #260 ):
      
      
        
          
            
              
258 
259 
260 
261 
262 
263 
               
             
    def call(env)
      @app.call(env)
    ensure
      session    = Request::Session.find(env) || {}
      flash_hash = env[KEY]
 
 
           
        
       
     
    
      
        Extracted source (around line #225 ):
      
      
        
          
            
              
223 
224 
225 
226 
227 
228 
               
             
        def context(env, app=@app)
          prepare_session(env)
          status, headers, body = app.call(env)
          commit_session(env, status, headers, body)
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #220 ):
      
      
        
          
            
              
218 
219 
220 
221 
222 
223 
               
             
        def call(env)
          context(env)
        end
        def context(env, app=@app)
 
 
           
        
       
     
    
      
        Extracted source (around line #560 ):
      
      
        
          
            
              
558 
559 
560 
561 
562 
563 
               
             
    def call(env)
      status, headers, body = @app.call(env)
      if cookie_jar = env['action_dispatch.cookies']
        unless cookie_jar.committed?
 
 
           
        
       
     
    
      
        Extracted source (around line #36 ):
      
      
        
          
            
              
34 
35 
36 
37 
38 
39 
               
             
      connection.enable_query_cache!
      response = @app.call(env)
      response[2] = Rack::BodyProxy.new(response[2]) do
        restore_query_cache_settings(connection_id, enabled)
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #653 ):
      
      
        
          
            
              
651 
652 
653 
654 
655 
656 
               
             
        testing = env['rack.test']
        response = @app.call(env)
        response[2] = ::Rack::BodyProxy.new(response[2]) do
          ActiveRecord::Base.clear_active_connections! unless testing
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #377 ):
      
      
        
          
            
              
375 
376 
377 
378 
379 
380 
               
             
          end
        end
        @app.call(env)
      end
      private
 
 
           
        
       
     
    
      
        Extracted source (around line #29 ):
      
      
        
          
            
              
27 
28 
29 
30 
31 
32 
               
             
      result = run_callbacks :call do
        begin
          @app.call(env)
        rescue => error
        end
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #88 ):
      
      
        
          
            
              
86 
87 
88 
89 
90 
91 
               
             
    def __run_callbacks__(callbacks, &block)
      if callbacks.empty?
        yield if block_given?
      else
        runner = callbacks.compile
        e = Filters::Environment.new(self, false, nil, block)
 
 
           
        
       
     
    
      
        Extracted source (around line #778 ):
      
      
        
          
            
              
776 
777 
778 
779 
780 
781 
               
             
          module_eval <<-RUBY, __FILE__, __LINE__ + 1
            def _run_#{name}_callbacks(&block)
              __run_callbacks__(_#{name}_callbacks, &block)
            end
          RUBY
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #81 ):
      
      
        
          
            
              
79 
80 
81 
82 
83 
84 
               
             
    #   end
    def run_callbacks(kind, &block)
      send "_run_#{kind}_callbacks", &block
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #27 ):
      
      
        
          
            
              
25 
26 
27 
28 
29 
30 
               
             
    def call(env)
      error = nil
      result = run_callbacks :call do
        begin
          @app.call(env)
        rescue => error
 
 
           
        
       
     
    
      
        Extracted source (around line #73 ):
      
      
        
          
            
              
71 
72 
73 
74 
75 
76 
               
             
      prepare!
      response = @app.call(env)
      response[2] = ::Rack::BodyProxy.new(response[2]) { cleanup! }
      response
 
 
           
        
       
     
    
      
        Extracted source (around line #78 ):
      
      
        
          
            
              
76 
77 
78 
79 
80 
81 
               
             
    def call(env)
      env["action_dispatch.remote_ip"] = GetIp.new(env, self)
      @app.call(env)
    end
    # The GetIp class exists as a way to defer processing of the request data
 
 
           
        
       
     
    
      
        Extracted source (around line #17 ):
      
      
        
          
            
              
15 
16 
17 
18 
19 
20 
               
             
    def call(env)
      _, headers, body = response = @app.call(env)
      if headers['X-Cascade'] == 'pass'
        body.close if body.respond_to?(:close)
 
 
           
        
       
     
    
      
        Extracted source (around line #28 ):
      
      
        
          
            
              
26 
27 
28 
29 
30 
31 
               
             
        end
        status, headers, body = @app.call(env)
        if exception = env['web_console.exception']
          session = Session.from_exception(exception)
 
 
           
        
       
     
    
      
        Extracted source (around line #18 ):
      
      
        
          
            
              
16 
17 
18 
19 
20 
21 
               
             
    def call(env)
      app_exception = catch :app_exception do
        request = create_regular_or_whiny_request(env)
        return @app.call(env) unless request.from_whitelited_ip?
 
 
           
        
       
     
    
      
        Extracted source (around line #18 ):
      
      
        
          
            
              
16 
17 
18 
19 
20 
21 
               
             
    def call(env)
      app_exception = catch :app_exception do
        request = create_regular_or_whiny_request(env)
        return @app.call(env) unless request.from_whitelited_ip?
 
 
           
        
       
     
    
      
        Extracted source (around line #30 ):
      
      
        
          
            
              
28 
29 
30 
31 
32 
33 
               
             
    def call(env)
      @app.call(env)
    rescue Exception => exception
      if env['action_dispatch.show_exceptions'] == false
        raise exception
 
 
           
        
       
     
    
      
        Extracted source (around line #38 ):
      
      
        
          
            
              
36 
37 
38 
39 
40 
41 
               
             
        instrumenter.start 'request.action_dispatch', request: request
        logger.info { started_request_message(request) }
        resp = @app.call(env)
        resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
        resp
      rescue Exception
 
 
           
        
       
     
    
      
        Extracted source (around line #20 ):
      
      
        
          
            
              
18 
19 
20 
21 
22 
23 
               
             
        if logger.respond_to?(:tagged)
          logger.tagged(compute_tags(request)) { call_app(request, env) }
        else
          call_app(request, env)
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #68 ):
      
      
        
          
            
              
66 
67 
68 
69 
70 
71 
               
             
    def tagged(*tags)
      formatter.tagged(*tags) { yield self }
    end
    def flush
 
 
           
        
       
     
    
      
        Extracted source (around line #26 ):
      
      
        
          
            
              
24 
25 
26 
27 
28 
29 
               
             
      def tagged(*tags)
        new_tags = push_tags(*tags)
        yield self
      ensure
        pop_tags(new_tags.size)
      end
 
 
           
        
       
     
    
      
        Extracted source (around line #68 ):
      
      
        
          
            
              
66 
67 
68 
69 
70 
71 
               
             
    def tagged(*tags)
      formatter.tagged(*tags) { yield self }
    end
    def flush
 
 
           
        
       
     
    
      
        Extracted source (around line #20 ):
      
      
        
          
            
              
18 
19 
20 
21 
22 
23 
               
             
        if logger.respond_to?(:tagged)
          logger.tagged(compute_tags(request)) { call_app(request, env) }
        else
          call_app(request, env)
        end
 
 
           
        
       
     
    
      
        Extracted source (around line #21 ):
      
      
        
          
            
              
19 
20 
21 
22 
23 
24 
               
             
    def call(env)
      env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id
      @app.call(env).tap { |_status, headers, _body| headers["X-Request-Id"] = env["action_dispatch.request_id"] }
    end
    private
 
 
           
        
       
     
    
      
        Extracted source (around line #22 ):
      
      
        
          
            
              
20 
21 
22 
23 
24 
25 
               
             
      end
      @app.call(env)
    end
    def method_override(env)
 
 
           
        
       
     
    
      
        Extracted source (around line #18 ):
      
      
        
          
            
              
16 
17 
18 
19 
20 
21 
               
             
    def call(env)
      start_time = clock_time
      status, headers, body = @app.call(env)
      request_time = clock_time - start_time
      if !headers.has_key?(@header_name)
 
 
           
        
       
     
    
      
        Extracted source (around line #28 ):
      
      
        
          
            
              
26 
27 
28 
29 
30 
31 
               
             
          def call(env)
            LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new)
            response = @app.call(env)
            response[2] = ::Rack::BodyProxy.new(response[2]) do
              LocalCacheRegistry.set_cache_for(local_cache_key, nil)
            end
 
 
           
        
       
     
    
      
        Extracted source (around line #17 ):
      
      
        
          
            
              
15 
16 
17 
18 
19 
20 
               
             
      old, env[FLAG] = env[FLAG], false
      @mutex.lock
      response = @app.call(env)
      body = BodyProxy.new(response[2]) { @mutex.unlock }
      response[2] = body
      response
 
 
           
        
       
     
    
      
        Extracted source (around line #120 ):
      
      
        
          
            
              
118 
119 
120 
121 
122 
123 
               
             
      end
      @app.call(env)
    end
  end
end
 
 
           
        
       
     
    
      
        Extracted source (around line #113 ):
      
      
        
          
            
              
111 
112 
113 
114 
115 
116 
               
             
    def call(env)
      status, headers, body = @app.call(env)
      if body.respond_to?(:to_path)
        case type = variation(env)
        when 'X-Accel-Redirect'
 
 
           
        
       
     
    
      
        Extracted source (around line #518 ):
      
      
        
          
            
              
516 
517 
518 
519 
520 
521 
               
             
        env["ROUTES_#{routes.object_id}_SCRIPT_NAME"] = env['SCRIPT_NAME'].dup
      end
      app.call(env)
    end
    # Defines additional Rack env configuration that is added on each call.
 
 
           
        
       
     
    
      
        Extracted source (around line #165 ):
      
      
        
          
            
              
163 
164 
165 
166 
167 
168 
               
             
      env["ORIGINAL_FULLPATH"] = build_original_fullpath(env)
      env["ORIGINAL_SCRIPT_NAME"] = env["SCRIPT_NAME"]
      super(env)
    end
    # Reload application routes regardless if they changed or not.
 
 
           
        
       
     
    
      
        Extracted source (around line #17 ):
      
      
        
          
            
              
15 
16 
17 
18 
19 
20 
               
             
      old, env[FLAG] = env[FLAG], false
      @mutex.lock
      response = @app.call(env)
      body = BodyProxy.new(response[2]) { @mutex.unlock }
      response[2] = body
      response
 
 
           
        
       
     
    
      
        Extracted source (around line #15 ):
      
      
        
          
            
              
13 
14 
15 
16 
17 
18 
               
             
    def call(env)
      status, headers, body = @app.call(env)
      headers = HeaderHash.new(headers)
      if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
 
 
           
        
       
     
    
      
        Extracted source (around line #88 ):
      
      
        
          
            
              
86 
87 
88 
89 
90 
91 
               
             
        env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env[PATH_INFO]].join
        status, headers, body = @app.call(env)
        begin
          res.status = status.to_i
          headers.each { |k, vs|
 
 
           
        
       
     
    
      
        Extracted source (around line #138 ):
      
      
        
          
            
              
136 
137 
138 
139 
140 
141 
               
             
      si = servlet.get_instance(self, *options)
      @logger.debug(format("%s is invoked.", si.class.name))
      si.service(req, res)
    end
    ##
 
 
           
        
       
     
    
      
        Extracted source (around line #94 ):
      
      
        
          
            
              
92 
93 
94 
95 
96 
97 
               
             
            callback.call(req, res)
          end
          server.service(req, res)
        rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
          res.set_error(ex)
        rescue HTTPStatus::Error => ex
 
 
           
        
       
     
    
      
        Extracted source (around line #294 ):
      
      
        
          
            
              
292 
293 
294 
295 
296 
297 
               
             
          end
          call_callback(:AcceptCallback, sock)
          block ? block.call(sock) : run(sock)
        rescue Errno::ENOTCONN
          @logger.debug "Errno::ENOTCONN raised"
        rescue ServerError => ex
 
 
           
        
       
     
  
  
Rails.root: /home/rubys/git/awdwr/edition4/work-226-42/depot
  
Request 
Parameters :
 None 
  
  _csrf_token: "VOTK4hVhtLsD7nJymDi+8NRL/0RAeqGDk+Ks/kVVjek="
cart_id: 2
session_id: "e3a1a24539de2b8c87ec6b5b12104e70"  
  
  GATEWAY_INTERFACE: "CGI/1.1"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
REMOTE_ADDR: "127.0.0.1"
REMOTE_HOST: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"  
Response 
Headers :
 None 
 
  
     
    
    Check for nil
    edit app/views/layouts/application.html.erb       <div id="side"> 
            <div id="cart"> 
              <% if @cart %> 
                <%= render @cart %> 
              <% end %> 
            </div> 
      
            <ul> 
              <li><a href="http://www....">Home</a></li> 
              <li><a href="http://www..../faq">Questions</a></li> 
              <li><a href="http://www..../news">News</a></li> 
              <li><a href="http://www..../contact">Contact</a></li> 
            </ul> 
          </div> 
    Update the redirect test.
    edit test/controllers/line_items_controller_test.rb   test "should create line_item" do 
        assert_difference('LineItem.count') do 
          post :create, product_id: products(:ruby).id 
        end 
      
        assert_redirected_to store_index_path 
      end 
    all better
    rake test Run options: --seed 18637 
      
    # Running: 
      
    .............................. 
      
    Finished in 0.456419s, 65.7290 runs/s, 164.3225 assertions/s. 
      
    30 runs, 75 assertions, 0 failures, 0 errors, 0 skips 
    
      11.2 Iteration F2: Creating an AJAX-Based Cart 
      10.4 Playtime