Agile Web Development with Rails, Edition 5
10.2 Iteration E2: Handling Errors
9.4 Playtime
10.1 Iteration E1: Creating a Smarter Cart
Expected exactly 3 elements matching "main li", found 6.
<3> expected but was
<6>.
Traceback:
/home/rubys/git/awdwr/edition4/checkdepot.rb:201:in `block in <class:DepotTest>'
Change the cart to track the quantity of each product.
Add a few products to the order.
get /
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=2
You are being
redirected .
get http://localhost:3000/carts/1
Line item was successfully created.
Your Pragmatic Cart
Seven Mobile Apps in Seven Weeks
Seven Mobile Apps in Seven Weeks
Rails, Angular, Postgres, and Bootstrap
get /
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=2
You are being
redirected .
get http://localhost:3000/carts/1
Line item was successfully created.
Your Pragmatic Cart
Seven Mobile Apps in Seven Weeks
Seven Mobile Apps in Seven Weeks
Rails, Angular, Postgres, and Bootstrap
Rails, Angular, Postgres, and Bootstrap
get /
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/carts/1
Line item was successfully created.
Your Pragmatic Cart
Seven Mobile Apps in Seven Weeks
Seven Mobile Apps in Seven Weeks
Rails, Angular, Postgres, and Bootstrap
Rails, Angular, Postgres, and Bootstrap
Seven Mobile Apps in Seven Weeks
Add a quantity column to the line_item table in the database.
rails generate migration add_quantity_to_line_items quantity:integer
invoke active_record
create db/migrate/20171113144110_add_quantity_to_line_items.rb
Modify the migration to add a default value for the new column
edit db/migrate/20171113144110_add_quantity_to_line_items.rb
class AddQuantityToLineItems < ActiveRecord::Migration[5.2]
def change
add_column :line_items, :quantity, :integer, default: 1
end
end
Apply the migration
rails db:migrate
mv 20171113144110_add_quantity_to_line_items.rb 20171113000004_add_quantity_to_line_items.rb
== 20171113000004 AddQuantityToLineItems: migrating ===========================
-- add_column(:line_items, :quantity, :integer, {:default=>1})
-> 0.0004s
== 20171113000004 AddQuantityToLineItems: migrated (0.0005s) ==================
Create a method to add a product to the cart by either incrementing the quantity of an existing line item, or creating a new line item.
edit app/models/cart.rb
def add_product(product)
current_item = line_items.find_by(product_id: product.id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product.id)
end
current_item
end
Replace the call to LineItem.new with a call to the new method.
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 @line_item.cart,
notice: 'Line item was successfully created.' }
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
Update the view to show both columns.
edit app/views/carts/show.html.erb
<% if notice %>
<aside id="notice"><%= notice %></aside>
<% end %>
<h2>Your Pragmatic Cart</h2>
<ul>
<% @cart.line_items.each do |item| %>
<li><%= item.quantity %> × <%= item.product.title %></li>
<% end %>
</ul>
Look at the cart, and see that's not exactly what we intended
get /carts/1
Your Pragmatic Cart
1 × Seven Mobile Apps in Seven Weeks
1 × Seven Mobile Apps in Seven Weeks
1 × Rails, Angular, Postgres, and Bootstrap
1 × Rails, Angular, Postgres, and Bootstrap
1 × Seven Mobile Apps in Seven Weeks
Generate a migration to combine/separate items in carts.
rails generate migration combine_items_in_cart
invoke active_record
create db/migrate/20171113144112_combine_items_in_cart.rb
Fill in the self.up method
edit db/migrate/20171113144112_combine_items_in_cart.rb
def up
# replace multiple items for a single product in a cart with a
# single item
Cart.all.each do |cart|
# count the number of each product in the cart
sums = cart.line_items.group(:product_id).sum(:quantity)
sums.each do |product_id, quantity|
if quantity > 1
# remove individual items
cart.line_items.where(product_id: product_id).delete_all
# replace with a single item
item = cart.line_items.build(product_id: product_id)
item.quantity = quantity
item.save!
end
end
end
end
Combine entries
rails db:migrate
mv 20171113144112_combine_items_in_cart.rb 20171113000005_combine_items_in_cart.rb
== 20171113000005 CombineItemsInCart: migrating ===============================
== 20171113000005 CombineItemsInCart: migrated (0.0234s) ======================
Verify that the entries have been combined.
get /carts/1
Your Pragmatic Cart
2 × Rails, Angular, Postgres, and Bootstrap
3 × Seven Mobile Apps in Seven Weeks
get /carts/2
HTTP Response Code: 404
ActiveRecord::RecordNotFound
in CartsController#show
Couldn't find Cart with 'id'=2
Extracted source (around line #162 ):
160
161
162
163
164
165
record = statement.execute([id], connection).first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
Extracted source (around line #67 ):
65
66
67
68
69
70
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
Extracted source (around line #426 ):
424
425
426
427
428
429
lambda do |target, value, &block|
target, block, method, *arguments = expand(target, value, block)
target.send(method, *arguments, &block)
end
end
Extracted source (around line #179 ):
177
178
179
180
181
182
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
Extracted source (around line #34 ):
32
33
34
35
36
37
included do
define_callbacks :process_action,
terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
skip_after_callbacks_if_terminated: true
end
Extracted source (around line #180 ):
178
179
180
181
182
183
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
end
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #131 ):
129
130
131
132
133
134
# Common case: no 'around' callbacks defined
if next_sequence.final?
next_sequence.invoke_before(env)
env.value = !env.halted && (!block_given? || yield)
next_sequence.invoke_after(env)
env.value
Extracted source (around line #41 ):
39
40
41
42
43
44
# <tt>process_action</tt> callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
Extracted source (around line #22 ):
20
21
22
23
24
25
private
def process_action(*args)
super
rescue Exception => exception
request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
rescue_with_handler(exception) || raise
Extracted source (around line #34 ):
32
33
34
35
36
37
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
result
ensure
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #23 ):
21
22
23
24
25
26
listeners_state = start name, payload
begin
yield payload
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
payload[:exception_object] = e
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #32 ):
30
31
32
33
34
35
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 #256 ):
254
255
256
257
258
259
request.filtered_parameters.merge! wrapped_filtered_hash
end
super
end
private
Extracted source (around line #24 ):
22
23
24
25
26
27
# 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 #134 ):
132
133
134
135
136
137
@_response_body = nil
process_action(action_name, *args)
end
# Delegates to the class' ::controller_path
Extracted source (around line #32 ):
30
31
32
33
34
35
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 #191 ):
189
190
191
192
193
194
set_request!(request)
set_response!(response)
process(name)
request.commit_flash
to_a
end
Extracted source (around line #254 ):
252
253
254
255
256
257
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
else
new.dispatch(name, req, res)
end
end
end
Extracted source (around line #52 ):
50
51
52
53
54
55
def dispatch(controller, action, req, res)
controller.dispatch(action, req, res)
end
end
Extracted source (around line #34 ):
32
33
34
35
36
37
controller = controller req
res = controller.make_response! req
dispatch(controller, params[:action], req, res)
rescue ActionController::RoutingError
if @raise_on_name_error
raise
Extracted source (around line #52 ):
50
51
52
53
54
55
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 #35 ):
33
34
35
36
37
38
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 #35 ):
33
34
35
36
37
38
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 #830 ):
828
829
830
831
832
833
req = make_request(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 #25 ):
23
24
25
26
27
28
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 #12 ):
10
11
12
13
14
15
def call(env)
status, headers, body = @app.call(env)
if env[REQUEST_METHOD] == HEAD
[
Extracted source (around line #232 ):
230
231
232
233
234
235
req = make_request env
prepare_session(req)
status, headers, body = app.call(req.env)
res = Rack::Response::Raw.new status, headers
commit_session(req, res)
[status, headers, body]
Extracted source (around line #226 ):
224
225
226
227
228
229
def call(env)
context(env)
end
def context(env, app=@app)
Extracted source (around line #663 ):
661
662
663
664
665
666
request = ActionDispatch::Request.new env
status, headers, body = @app.call(env)
if request.have_cookie_jar?
cookie_jar = request.cookie_jar
Extracted source (around line #558 ):
556
557
558
559
560
561
@last_check = mtime
end
@app.call(env)
end
private
Extracted source (around line #28 ):
26
27
28
29
30
31
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
end
end
Extracted source (around line #98 ):
96
97
98
99
100
101
if callbacks.empty?
yield if block_given?
else
env = Filters::Environment.new(self, false, nil)
next_sequence = callbacks.compile
Extracted source (around line #26 ):
24
25
26
27
28
29
def call(env)
error = nil
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
Extracted source (around line #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #61 ):
59
60
61
62
63
64
def call(env)
request = ActionDispatch::Request.new env
_, headers, body = response = @app.call(env)
if headers["X-Cascade"] == "pass"
body.close if body.respond_to?(:close)
Extracted source (around line #137 ):
135
136
137
138
139
140
def call_app(env)
@app.call(env)
rescue => e
throw :app_exception, e
end
Extracted source (around line #30 ):
28
29
30
31
32
33
end
status, headers, body = call_app(env)
if session = Session.from(Thread.current) and acceptable_content_type?(headers)
response = Response.new(body, status, headers)
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #33 ):
31
32
33
34
35
36
def call(env)
request = ActionDispatch::Request.new env
@app.call(env)
rescue Exception => exception
if request.show_exceptions?
render_exception(request, 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 #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #28 ):
26
27
28
29
30
31
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #13 ):
11
12
13
14
15
16
::Rails.logger.silence { @app.call(env) }
else
@app.call(env)
end
end
end
Extracted source (around line #81 ):
79
80
81
82
83
84
req = ActionDispatch::Request.new env
req.remote_ip = GetIp.new(req, check_ip, proxies)
@app.call(req.env)
end
# The GetIp class exists as a way to defer processing of the request data
Extracted source (around line #27 ):
25
26
27
28
29
30
req = ActionDispatch::Request.new env
req.request_id = make_request_id(req.x_request_id)
@app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.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 #22 ):
20
21
22
23
24
25
def call(env)
start_time = Utils.clock_time
status, headers, body = @app.call(env)
request_time = Utils.clock_time - start_time
unless headers.has_key?(@header_name)
Extracted source (around line #29 ):
27
28
29
30
31
32
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 #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #127 ):
125
126
127
128
129
130
end
@app.call(req.env)
end
end
end
Extracted source (around line #111 ):
109
110
111
112
113
114
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 #524 ):
522
523
524
525
526
527
def call(env)
req = build_request env
app.call req.env
end
# Defines additional Rack env configuration that is added on each call.
Extracted source (around line #225 ):
223
224
225
226
227
228
def call(env)
env[Const::PUMA_CONFIG] = @config
@app.call(env)
end
end
Extracted source (around line #605 ):
603
604
605
606
607
608
begin
begin
status, headers, res_body = @app.call(env)
return :async if req.hijacked
Extracted source (around line #437 ):
435
436
437
438
439
440
while true
case handle_request(client, buffer)
when false
return
when :async
Extracted source (around line #301 ):
299
300
301
302
303
304
else
if process_now
process_client client, buffer
else
client.set_timeout @first_data_timeout
@reactor.add client
Extracted source (around line #120 ):
118
119
120
121
122
123
begin
block.call(work, *extra)
rescue Exception => e
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
end
Rails.root: /home/rubys/git/awdwr/edition4/work/depot
Request
Parameters :
{"id"=>"2"}
_csrf_token: "Ik0swwjSqEegZDNnoKYWQ7xwe7XTNxccCP4OLt5Ny0c="
cart_id: 1
session_id: "de81ce2ce6a5a9dc4c201a7339c344eb"
GATEWAY_INTERFACE: "CGI/1.2"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
HTTP_VERSION: "HTTP/1.1"
ORIGINAL_SCRIPT_NAME: ""
REMOTE_ADDR: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"
Response
Headers :
None
get /carts/3
HTTP Response Code: 404
ActiveRecord::RecordNotFound
in CartsController#show
Couldn't find Cart with 'id'=3
Extracted source (around line #162 ):
160
161
162
163
164
165
record = statement.execute([id], connection).first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
Extracted source (around line #67 ):
65
66
67
68
69
70
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
Extracted source (around line #426 ):
424
425
426
427
428
429
lambda do |target, value, &block|
target, block, method, *arguments = expand(target, value, block)
target.send(method, *arguments, &block)
end
end
Extracted source (around line #179 ):
177
178
179
180
181
182
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
Extracted source (around line #34 ):
32
33
34
35
36
37
included do
define_callbacks :process_action,
terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
skip_after_callbacks_if_terminated: true
end
Extracted source (around line #180 ):
178
179
180
181
182
183
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
end
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #131 ):
129
130
131
132
133
134
# Common case: no 'around' callbacks defined
if next_sequence.final?
next_sequence.invoke_before(env)
env.value = !env.halted && (!block_given? || yield)
next_sequence.invoke_after(env)
env.value
Extracted source (around line #41 ):
39
40
41
42
43
44
# <tt>process_action</tt> callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
Extracted source (around line #22 ):
20
21
22
23
24
25
private
def process_action(*args)
super
rescue Exception => exception
request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
rescue_with_handler(exception) || raise
Extracted source (around line #34 ):
32
33
34
35
36
37
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
result
ensure
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #23 ):
21
22
23
24
25
26
listeners_state = start name, payload
begin
yield payload
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
payload[:exception_object] = e
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #32 ):
30
31
32
33
34
35
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 #256 ):
254
255
256
257
258
259
request.filtered_parameters.merge! wrapped_filtered_hash
end
super
end
private
Extracted source (around line #24 ):
22
23
24
25
26
27
# 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 #134 ):
132
133
134
135
136
137
@_response_body = nil
process_action(action_name, *args)
end
# Delegates to the class' ::controller_path
Extracted source (around line #32 ):
30
31
32
33
34
35
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 #191 ):
189
190
191
192
193
194
set_request!(request)
set_response!(response)
process(name)
request.commit_flash
to_a
end
Extracted source (around line #254 ):
252
253
254
255
256
257
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
else
new.dispatch(name, req, res)
end
end
end
Extracted source (around line #52 ):
50
51
52
53
54
55
def dispatch(controller, action, req, res)
controller.dispatch(action, req, res)
end
end
Extracted source (around line #34 ):
32
33
34
35
36
37
controller = controller req
res = controller.make_response! req
dispatch(controller, params[:action], req, res)
rescue ActionController::RoutingError
if @raise_on_name_error
raise
Extracted source (around line #52 ):
50
51
52
53
54
55
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 #35 ):
33
34
35
36
37
38
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 #35 ):
33
34
35
36
37
38
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 #830 ):
828
829
830
831
832
833
req = make_request(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 #25 ):
23
24
25
26
27
28
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 #12 ):
10
11
12
13
14
15
def call(env)
status, headers, body = @app.call(env)
if env[REQUEST_METHOD] == HEAD
[
Extracted source (around line #232 ):
230
231
232
233
234
235
req = make_request env
prepare_session(req)
status, headers, body = app.call(req.env)
res = Rack::Response::Raw.new status, headers
commit_session(req, res)
[status, headers, body]
Extracted source (around line #226 ):
224
225
226
227
228
229
def call(env)
context(env)
end
def context(env, app=@app)
Extracted source (around line #663 ):
661
662
663
664
665
666
request = ActionDispatch::Request.new env
status, headers, body = @app.call(env)
if request.have_cookie_jar?
cookie_jar = request.cookie_jar
Extracted source (around line #558 ):
556
557
558
559
560
561
@last_check = mtime
end
@app.call(env)
end
private
Extracted source (around line #28 ):
26
27
28
29
30
31
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
end
end
Extracted source (around line #98 ):
96
97
98
99
100
101
if callbacks.empty?
yield if block_given?
else
env = Filters::Environment.new(self, false, nil)
next_sequence = callbacks.compile
Extracted source (around line #26 ):
24
25
26
27
28
29
def call(env)
error = nil
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
Extracted source (around line #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #61 ):
59
60
61
62
63
64
def call(env)
request = ActionDispatch::Request.new env
_, headers, body = response = @app.call(env)
if headers["X-Cascade"] == "pass"
body.close if body.respond_to?(:close)
Extracted source (around line #137 ):
135
136
137
138
139
140
def call_app(env)
@app.call(env)
rescue => e
throw :app_exception, e
end
Extracted source (around line #30 ):
28
29
30
31
32
33
end
status, headers, body = call_app(env)
if session = Session.from(Thread.current) and acceptable_content_type?(headers)
response = Response.new(body, status, headers)
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #33 ):
31
32
33
34
35
36
def call(env)
request = ActionDispatch::Request.new env
@app.call(env)
rescue Exception => exception
if request.show_exceptions?
render_exception(request, 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 #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #28 ):
26
27
28
29
30
31
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #13 ):
11
12
13
14
15
16
::Rails.logger.silence { @app.call(env) }
else
@app.call(env)
end
end
end
Extracted source (around line #81 ):
79
80
81
82
83
84
req = ActionDispatch::Request.new env
req.remote_ip = GetIp.new(req, check_ip, proxies)
@app.call(req.env)
end
# The GetIp class exists as a way to defer processing of the request data
Extracted source (around line #27 ):
25
26
27
28
29
30
req = ActionDispatch::Request.new env
req.request_id = make_request_id(req.x_request_id)
@app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.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 #22 ):
20
21
22
23
24
25
def call(env)
start_time = Utils.clock_time
status, headers, body = @app.call(env)
request_time = Utils.clock_time - start_time
unless headers.has_key?(@header_name)
Extracted source (around line #29 ):
27
28
29
30
31
32
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 #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #127 ):
125
126
127
128
129
130
end
@app.call(req.env)
end
end
end
Extracted source (around line #111 ):
109
110
111
112
113
114
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 #524 ):
522
523
524
525
526
527
def call(env)
req = build_request env
app.call req.env
end
# Defines additional Rack env configuration that is added on each call.
Extracted source (around line #225 ):
223
224
225
226
227
228
def call(env)
env[Const::PUMA_CONFIG] = @config
@app.call(env)
end
end
Extracted source (around line #605 ):
603
604
605
606
607
608
begin
begin
status, headers, res_body = @app.call(env)
return :async if req.hijacked
Extracted source (around line #437 ):
435
436
437
438
439
440
while true
case handle_request(client, buffer)
when false
return
when :async
Extracted source (around line #301 ):
299
300
301
302
303
304
else
if process_now
process_client client, buffer
else
client.set_timeout @first_data_timeout
@reactor.add client
Extracted source (around line #120 ):
118
119
120
121
122
123
begin
block.call(work, *extra)
rescue Exception => e
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
end
Rails.root: /home/rubys/git/awdwr/edition4/work/depot
Request
Parameters :
{"id"=>"3"}
_csrf_token: "Ik0swwjSqEegZDNnoKYWQ7xwe7XTNxccCP4OLt5Ny0c="
cart_id: 1
session_id: "de81ce2ce6a5a9dc4c201a7339c344eb"
GATEWAY_INTERFACE: "CGI/1.2"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
HTTP_VERSION: "HTTP/1.1"
ORIGINAL_SCRIPT_NAME: ""
REMOTE_ADDR: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"
Response
Headers :
None
Fill in the self.down method
edit db/migrate/20171113000005_combine_items_in_cart.rb
def down
# split items with quantity>1 into multiple items
LineItem.where("quantity>1").each do |line_item|
# add individual items
line_item.quantity.times do
LineItem.create(
cart_id: line_item.cart_id,
product_id: line_item.product_id,
quantity: 1
)
end
# remove original item
line_item.destroy
end
end
Separate out individual items.
rails db:rollback
== 20171113000005 CombineItemsInCart: reverting ===============================
== 20171113000005 CombineItemsInCart: reverted (0.0265s) ======================
rails db:migrate:status
database: /home/rubys/git/awdwr/edition4/work/depot/db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20171113000001 Create products
up 20171113000002 Create carts
up 20171113000003 Create line items
up 20171113000004 Add quantity to line items
down 20171113000005 Combine items in cart
mv db/migrate/20171113000005_combine_items_in_cart.rb db/migrate/20171113000005_combine_items_in_cart.bak
Every item should (once again) only have a quantity of one.
get /carts/1
Your Pragmatic Cart
1 × Rails, Angular, Postgres, and Bootstrap
1 × Rails, Angular, Postgres, and Bootstrap
1 × Seven Mobile Apps in Seven Weeks
1 × Seven Mobile Apps in Seven Weeks
1 × Seven Mobile Apps in Seven Weeks
get /carts/2
HTTP Response Code: 404
ActiveRecord::RecordNotFound
in CartsController#show
Couldn't find Cart with 'id'=2
Extracted source (around line #162 ):
160
161
162
163
164
165
record = statement.execute([id], connection).first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
Extracted source (around line #67 ):
65
66
67
68
69
70
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
Extracted source (around line #426 ):
424
425
426
427
428
429
lambda do |target, value, &block|
target, block, method, *arguments = expand(target, value, block)
target.send(method, *arguments, &block)
end
end
Extracted source (around line #179 ):
177
178
179
180
181
182
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
Extracted source (around line #34 ):
32
33
34
35
36
37
included do
define_callbacks :process_action,
terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
skip_after_callbacks_if_terminated: true
end
Extracted source (around line #180 ):
178
179
180
181
182
183
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
end
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #131 ):
129
130
131
132
133
134
# Common case: no 'around' callbacks defined
if next_sequence.final?
next_sequence.invoke_before(env)
env.value = !env.halted && (!block_given? || yield)
next_sequence.invoke_after(env)
env.value
Extracted source (around line #41 ):
39
40
41
42
43
44
# <tt>process_action</tt> callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
Extracted source (around line #22 ):
20
21
22
23
24
25
private
def process_action(*args)
super
rescue Exception => exception
request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
rescue_with_handler(exception) || raise
Extracted source (around line #34 ):
32
33
34
35
36
37
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
result
ensure
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #23 ):
21
22
23
24
25
26
listeners_state = start name, payload
begin
yield payload
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
payload[:exception_object] = e
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #32 ):
30
31
32
33
34
35
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 #256 ):
254
255
256
257
258
259
request.filtered_parameters.merge! wrapped_filtered_hash
end
super
end
private
Extracted source (around line #24 ):
22
23
24
25
26
27
# 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 #134 ):
132
133
134
135
136
137
@_response_body = nil
process_action(action_name, *args)
end
# Delegates to the class' ::controller_path
Extracted source (around line #32 ):
30
31
32
33
34
35
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 #191 ):
189
190
191
192
193
194
set_request!(request)
set_response!(response)
process(name)
request.commit_flash
to_a
end
Extracted source (around line #254 ):
252
253
254
255
256
257
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
else
new.dispatch(name, req, res)
end
end
end
Extracted source (around line #52 ):
50
51
52
53
54
55
def dispatch(controller, action, req, res)
controller.dispatch(action, req, res)
end
end
Extracted source (around line #34 ):
32
33
34
35
36
37
controller = controller req
res = controller.make_response! req
dispatch(controller, params[:action], req, res)
rescue ActionController::RoutingError
if @raise_on_name_error
raise
Extracted source (around line #52 ):
50
51
52
53
54
55
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 #35 ):
33
34
35
36
37
38
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 #35 ):
33
34
35
36
37
38
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 #830 ):
828
829
830
831
832
833
req = make_request(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 #25 ):
23
24
25
26
27
28
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 #12 ):
10
11
12
13
14
15
def call(env)
status, headers, body = @app.call(env)
if env[REQUEST_METHOD] == HEAD
[
Extracted source (around line #232 ):
230
231
232
233
234
235
req = make_request env
prepare_session(req)
status, headers, body = app.call(req.env)
res = Rack::Response::Raw.new status, headers
commit_session(req, res)
[status, headers, body]
Extracted source (around line #226 ):
224
225
226
227
228
229
def call(env)
context(env)
end
def context(env, app=@app)
Extracted source (around line #663 ):
661
662
663
664
665
666
request = ActionDispatch::Request.new env
status, headers, body = @app.call(env)
if request.have_cookie_jar?
cookie_jar = request.cookie_jar
Extracted source (around line #558 ):
556
557
558
559
560
561
@last_check = mtime
end
@app.call(env)
end
private
Extracted source (around line #28 ):
26
27
28
29
30
31
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
end
end
Extracted source (around line #98 ):
96
97
98
99
100
101
if callbacks.empty?
yield if block_given?
else
env = Filters::Environment.new(self, false, nil)
next_sequence = callbacks.compile
Extracted source (around line #26 ):
24
25
26
27
28
29
def call(env)
error = nil
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
Extracted source (around line #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #61 ):
59
60
61
62
63
64
def call(env)
request = ActionDispatch::Request.new env
_, headers, body = response = @app.call(env)
if headers["X-Cascade"] == "pass"
body.close if body.respond_to?(:close)
Extracted source (around line #137 ):
135
136
137
138
139
140
def call_app(env)
@app.call(env)
rescue => e
throw :app_exception, e
end
Extracted source (around line #30 ):
28
29
30
31
32
33
end
status, headers, body = call_app(env)
if session = Session.from(Thread.current) and acceptable_content_type?(headers)
response = Response.new(body, status, headers)
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #33 ):
31
32
33
34
35
36
def call(env)
request = ActionDispatch::Request.new env
@app.call(env)
rescue Exception => exception
if request.show_exceptions?
render_exception(request, 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 #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #28 ):
26
27
28
29
30
31
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #13 ):
11
12
13
14
15
16
::Rails.logger.silence { @app.call(env) }
else
@app.call(env)
end
end
end
Extracted source (around line #81 ):
79
80
81
82
83
84
req = ActionDispatch::Request.new env
req.remote_ip = GetIp.new(req, check_ip, proxies)
@app.call(req.env)
end
# The GetIp class exists as a way to defer processing of the request data
Extracted source (around line #27 ):
25
26
27
28
29
30
req = ActionDispatch::Request.new env
req.request_id = make_request_id(req.x_request_id)
@app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.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 #22 ):
20
21
22
23
24
25
def call(env)
start_time = Utils.clock_time
status, headers, body = @app.call(env)
request_time = Utils.clock_time - start_time
unless headers.has_key?(@header_name)
Extracted source (around line #29 ):
27
28
29
30
31
32
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 #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #127 ):
125
126
127
128
129
130
end
@app.call(req.env)
end
end
end
Extracted source (around line #111 ):
109
110
111
112
113
114
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 #524 ):
522
523
524
525
526
527
def call(env)
req = build_request env
app.call req.env
end
# Defines additional Rack env configuration that is added on each call.
Extracted source (around line #225 ):
223
224
225
226
227
228
def call(env)
env[Const::PUMA_CONFIG] = @config
@app.call(env)
end
end
Extracted source (around line #605 ):
603
604
605
606
607
608
begin
begin
status, headers, res_body = @app.call(env)
return :async if req.hijacked
Extracted source (around line #437 ):
435
436
437
438
439
440
while true
case handle_request(client, buffer)
when false
return
when :async
Extracted source (around line #301 ):
299
300
301
302
303
304
else
if process_now
process_client client, buffer
else
client.set_timeout @first_data_timeout
@reactor.add client
Extracted source (around line #120 ):
118
119
120
121
122
123
begin
block.call(work, *extra)
rescue Exception => e
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
end
Rails.root: /home/rubys/git/awdwr/edition4/work/depot
Request
Parameters :
{"id"=>"2"}
_csrf_token: "Ik0swwjSqEegZDNnoKYWQ7xwe7XTNxccCP4OLt5Ny0c="
cart_id: 1
session_id: "de81ce2ce6a5a9dc4c201a7339c344eb"
GATEWAY_INTERFACE: "CGI/1.2"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
HTTP_VERSION: "HTTP/1.1"
ORIGINAL_SCRIPT_NAME: ""
REMOTE_ADDR: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"
Response
Headers :
None
get /carts/3
HTTP Response Code: 404
ActiveRecord::RecordNotFound
in CartsController#show
Couldn't find Cart with 'id'=3
Extracted source (around line #162 ):
160
161
162
163
164
165
record = statement.execute([id], connection).first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
Extracted source (around line #67 ):
65
66
67
68
69
70
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
Extracted source (around line #426 ):
424
425
426
427
428
429
lambda do |target, value, &block|
target, block, method, *arguments = expand(target, value, block)
target.send(method, *arguments, &block)
end
end
Extracted source (around line #179 ):
177
178
179
180
181
182
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
Extracted source (around line #34 ):
32
33
34
35
36
37
included do
define_callbacks :process_action,
terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
skip_after_callbacks_if_terminated: true
end
Extracted source (around line #180 ):
178
179
180
181
182
183
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
end
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #131 ):
129
130
131
132
133
134
# Common case: no 'around' callbacks defined
if next_sequence.final?
next_sequence.invoke_before(env)
env.value = !env.halted && (!block_given? || yield)
next_sequence.invoke_after(env)
env.value
Extracted source (around line #41 ):
39
40
41
42
43
44
# <tt>process_action</tt> callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
Extracted source (around line #22 ):
20
21
22
23
24
25
private
def process_action(*args)
super
rescue Exception => exception
request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
rescue_with_handler(exception) || raise
Extracted source (around line #34 ):
32
33
34
35
36
37
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
result
ensure
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #23 ):
21
22
23
24
25
26
listeners_state = start name, payload
begin
yield payload
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
payload[:exception_object] = e
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #32 ):
30
31
32
33
34
35
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 #256 ):
254
255
256
257
258
259
request.filtered_parameters.merge! wrapped_filtered_hash
end
super
end
private
Extracted source (around line #24 ):
22
23
24
25
26
27
# 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 #134 ):
132
133
134
135
136
137
@_response_body = nil
process_action(action_name, *args)
end
# Delegates to the class' ::controller_path
Extracted source (around line #32 ):
30
31
32
33
34
35
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 #191 ):
189
190
191
192
193
194
set_request!(request)
set_response!(response)
process(name)
request.commit_flash
to_a
end
Extracted source (around line #254 ):
252
253
254
255
256
257
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
else
new.dispatch(name, req, res)
end
end
end
Extracted source (around line #52 ):
50
51
52
53
54
55
def dispatch(controller, action, req, res)
controller.dispatch(action, req, res)
end
end
Extracted source (around line #34 ):
32
33
34
35
36
37
controller = controller req
res = controller.make_response! req
dispatch(controller, params[:action], req, res)
rescue ActionController::RoutingError
if @raise_on_name_error
raise
Extracted source (around line #52 ):
50
51
52
53
54
55
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 #35 ):
33
34
35
36
37
38
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 #35 ):
33
34
35
36
37
38
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 #830 ):
828
829
830
831
832
833
req = make_request(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 #25 ):
23
24
25
26
27
28
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 #12 ):
10
11
12
13
14
15
def call(env)
status, headers, body = @app.call(env)
if env[REQUEST_METHOD] == HEAD
[
Extracted source (around line #232 ):
230
231
232
233
234
235
req = make_request env
prepare_session(req)
status, headers, body = app.call(req.env)
res = Rack::Response::Raw.new status, headers
commit_session(req, res)
[status, headers, body]
Extracted source (around line #226 ):
224
225
226
227
228
229
def call(env)
context(env)
end
def context(env, app=@app)
Extracted source (around line #663 ):
661
662
663
664
665
666
request = ActionDispatch::Request.new env
status, headers, body = @app.call(env)
if request.have_cookie_jar?
cookie_jar = request.cookie_jar
Extracted source (around line #558 ):
556
557
558
559
560
561
@last_check = mtime
end
@app.call(env)
end
private
Extracted source (around line #28 ):
26
27
28
29
30
31
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
end
end
Extracted source (around line #98 ):
96
97
98
99
100
101
if callbacks.empty?
yield if block_given?
else
env = Filters::Environment.new(self, false, nil)
next_sequence = callbacks.compile
Extracted source (around line #26 ):
24
25
26
27
28
29
def call(env)
error = nil
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
Extracted source (around line #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #61 ):
59
60
61
62
63
64
def call(env)
request = ActionDispatch::Request.new env
_, headers, body = response = @app.call(env)
if headers["X-Cascade"] == "pass"
body.close if body.respond_to?(:close)
Extracted source (around line #137 ):
135
136
137
138
139
140
def call_app(env)
@app.call(env)
rescue => e
throw :app_exception, e
end
Extracted source (around line #30 ):
28
29
30
31
32
33
end
status, headers, body = call_app(env)
if session = Session.from(Thread.current) and acceptable_content_type?(headers)
response = Response.new(body, status, headers)
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #33 ):
31
32
33
34
35
36
def call(env)
request = ActionDispatch::Request.new env
@app.call(env)
rescue Exception => exception
if request.show_exceptions?
render_exception(request, 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 #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #28 ):
26
27
28
29
30
31
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #13 ):
11
12
13
14
15
16
::Rails.logger.silence { @app.call(env) }
else
@app.call(env)
end
end
end
Extracted source (around line #81 ):
79
80
81
82
83
84
req = ActionDispatch::Request.new env
req.remote_ip = GetIp.new(req, check_ip, proxies)
@app.call(req.env)
end
# The GetIp class exists as a way to defer processing of the request data
Extracted source (around line #27 ):
25
26
27
28
29
30
req = ActionDispatch::Request.new env
req.request_id = make_request_id(req.x_request_id)
@app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.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 #22 ):
20
21
22
23
24
25
def call(env)
start_time = Utils.clock_time
status, headers, body = @app.call(env)
request_time = Utils.clock_time - start_time
unless headers.has_key?(@header_name)
Extracted source (around line #29 ):
27
28
29
30
31
32
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 #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #127 ):
125
126
127
128
129
130
end
@app.call(req.env)
end
end
end
Extracted source (around line #111 ):
109
110
111
112
113
114
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 #524 ):
522
523
524
525
526
527
def call(env)
req = build_request env
app.call req.env
end
# Defines additional Rack env configuration that is added on each call.
Extracted source (around line #225 ):
223
224
225
226
227
228
def call(env)
env[Const::PUMA_CONFIG] = @config
@app.call(env)
end
end
Extracted source (around line #605 ):
603
604
605
606
607
608
begin
begin
status, headers, res_body = @app.call(env)
return :async if req.hijacked
Extracted source (around line #437 ):
435
436
437
438
439
440
while true
case handle_request(client, buffer)
when false
return
when :async
Extracted source (around line #301 ):
299
300
301
302
303
304
else
if process_now
process_client client, buffer
else
client.set_timeout @first_data_timeout
@reactor.add client
Extracted source (around line #120 ):
118
119
120
121
122
123
begin
block.call(work, *extra)
rescue Exception => e
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
end
Rails.root: /home/rubys/git/awdwr/edition4/work/depot
Request
Parameters :
{"id"=>"3"}
_csrf_token: "Ik0swwjSqEegZDNnoKYWQ7xwe7XTNxccCP4OLt5Ny0c="
cart_id: 1
session_id: "de81ce2ce6a5a9dc4c201a7339c344eb"
GATEWAY_INTERFACE: "CGI/1.2"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
HTTP_VERSION: "HTTP/1.1"
ORIGINAL_SCRIPT_NAME: ""
REMOTE_ADDR: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"
Response
Headers :
None
Recombine the item data.
mv db/migrate/20171113000005_combine_items_in_cart.bak db/migrate/20171113000005_combine_items_in_cart.rb
rails db:migrate
== 20171113000005 CombineItemsInCart: migrating ===============================
== 20171113000005 CombineItemsInCart: migrated (0.0229s) ======================
Add a few products to the order.
post /line_items?product_id=2
You are being
redirected .
get http://localhost:3000/carts/1
Line item was successfully created.
Your Pragmatic Cart
3 × Rails, Angular, Postgres, and Bootstrap
3 × Seven Mobile Apps in Seven Weeks
post /line_items?product_id=3
You are being
redirected .
get http://localhost:3000/carts/1
Line item was successfully created.
Your Pragmatic Cart
3 × Rails, Angular, Postgres, and Bootstrap
4 × Seven Mobile Apps in Seven Weeks
fix the test case
edit test/controllers/line_items_controller_test.rb
test "should create line_item" do
assert_difference('LineItem.count') do
post line_items_url, params: { product_id: products(:ruby).id }
end
follow_redirect!
assert_select 'h2', 'Your Pragmatic Cart'
assert_select 'li', "1 \u00D7 Programming Ruby 1.9"
end
rerun tests
rails test
Run options: --seed 15927
# Running:
............................
Finished in 0.394189s, 71.0318 runs/s, 147.1374 assertions/s.
28 runs, 58 assertions, 0 failures, 0 errors, 0 skips
Try something malicious.
get /carts/wibble
HTTP Response Code: 404
ActiveRecord::RecordNotFound
in CartsController#show
Couldn't find Cart with 'id'=wibble
Extracted source (around line #162 ):
160
161
162
163
164
165
record = statement.execute([id], connection).first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
Extracted source (around line #67 ):
65
66
67
68
69
70
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
Extracted source (around line #426 ):
424
425
426
427
428
429
lambda do |target, value, &block|
target, block, method, *arguments = expand(target, value, block)
target.send(method, *arguments, &block)
end
end
Extracted source (around line #179 ):
177
178
179
180
181
182
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
Extracted source (around line #34 ):
32
33
34
35
36
37
included do
define_callbacks :process_action,
terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
skip_after_callbacks_if_terminated: true
end
Extracted source (around line #180 ):
178
179
180
181
182
183
if !halted && user_conditions.all? { |c| c.call(target, value) }
result_lambda = -> { user_callback.call target, value }
env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
end
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #513 ):
511
512
513
514
515
516
def invoke_before(arg)
@before.each { |b| b.call(arg) }
end
def invoke_after(arg)
Extracted source (around line #131 ):
129
130
131
132
133
134
# Common case: no 'around' callbacks defined
if next_sequence.final?
next_sequence.invoke_before(env)
env.value = !env.halted && (!block_given? || yield)
next_sequence.invoke_after(env)
env.value
Extracted source (around line #41 ):
39
40
41
42
43
44
# <tt>process_action</tt> callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end
Extracted source (around line #22 ):
20
21
22
23
24
25
private
def process_action(*args)
super
rescue Exception => exception
request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
rescue_with_handler(exception) || raise
Extracted source (around line #34 ):
32
33
34
35
36
37
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
begin
result = super
payload[:status] = response.status
result
ensure
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #23 ):
21
22
23
24
25
26
listeners_state = start name, payload
begin
yield payload
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
payload[:exception_object] = e
Extracted source (around line #168 ):
166
167
168
169
170
171
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 #32 ):
30
31
32
33
34
35
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 #256 ):
254
255
256
257
258
259
request.filtered_parameters.merge! wrapped_filtered_hash
end
super
end
private
Extracted source (around line #24 ):
22
23
24
25
26
27
# 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 #134 ):
132
133
134
135
136
137
@_response_body = nil
process_action(action_name, *args)
end
# Delegates to the class' ::controller_path
Extracted source (around line #32 ):
30
31
32
33
34
35
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 #191 ):
189
190
191
192
193
194
set_request!(request)
set_response!(response)
process(name)
request.commit_flash
to_a
end
Extracted source (around line #254 ):
252
253
254
255
256
257
middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
else
new.dispatch(name, req, res)
end
end
end
Extracted source (around line #52 ):
50
51
52
53
54
55
def dispatch(controller, action, req, res)
controller.dispatch(action, req, res)
end
end
Extracted source (around line #34 ):
32
33
34
35
36
37
controller = controller req
res = controller.make_response! req
dispatch(controller, params[:action], req, res)
rescue ActionController::RoutingError
if @raise_on_name_error
raise
Extracted source (around line #52 ):
50
51
52
53
54
55
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 #35 ):
33
34
35
36
37
38
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 #35 ):
33
34
35
36
37
38
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 #830 ):
828
829
830
831
832
833
req = make_request(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 #25 ):
23
24
25
26
27
28
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 #12 ):
10
11
12
13
14
15
def call(env)
status, headers, body = @app.call(env)
if env[REQUEST_METHOD] == HEAD
[
Extracted source (around line #232 ):
230
231
232
233
234
235
req = make_request env
prepare_session(req)
status, headers, body = app.call(req.env)
res = Rack::Response::Raw.new status, headers
commit_session(req, res)
[status, headers, body]
Extracted source (around line #226 ):
224
225
226
227
228
229
def call(env)
context(env)
end
def context(env, app=@app)
Extracted source (around line #663 ):
661
662
663
664
665
666
request = ActionDispatch::Request.new env
status, headers, body = @app.call(env)
if request.have_cookie_jar?
cookie_jar = request.cookie_jar
Extracted source (around line #558 ):
556
557
558
559
560
561
@last_check = mtime
end
@app.call(env)
end
private
Extracted source (around line #28 ):
26
27
28
29
30
31
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
end
end
Extracted source (around line #98 ):
96
97
98
99
100
101
if callbacks.empty?
yield if block_given?
else
env = Filters::Environment.new(self, false, nil)
next_sequence = callbacks.compile
Extracted source (around line #26 ):
24
25
26
27
28
29
def call(env)
error = nil
result = run_callbacks :call do
begin
@app.call(env)
rescue => error
Extracted source (around line #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #61 ):
59
60
61
62
63
64
def call(env)
request = ActionDispatch::Request.new env
_, headers, body = response = @app.call(env)
if headers["X-Cascade"] == "pass"
body.close if body.respond_to?(:close)
Extracted source (around line #137 ):
135
136
137
138
139
140
def call_app(env)
@app.call(env)
rescue => e
throw :app_exception, e
end
Extracted source (around line #30 ):
28
29
30
31
32
33
end
status, headers, body = call_app(env)
if session = Session.from(Thread.current) and acceptable_content_type?(headers)
response = Response.new(body, status, headers)
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #20 ):
18
19
20
21
22
23
def call(env)
app_exception = catch :app_exception do
request = create_regular_or_whiny_request(env)
return call_app(env) unless request.from_whitelisted_ip?
Extracted source (around line #33 ):
31
32
33
34
35
36
def call(env)
request = ActionDispatch::Request.new env
@app.call(env)
rescue Exception => exception
if request.show_exceptions?
render_exception(request, 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 #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #28 ):
26
27
28
29
30
31
def tagged(*tags)
new_tags = push_tags(*tags)
yield self
ensure
pop_tags(new_tags.size)
end
Extracted source (around line #71 ):
69
70
71
72
73
74
def tagged(*tags)
formatter.tagged(*tags) { yield self }
end
def flush
Extracted source (around line #26 ):
24
25
26
27
28
29
if logger.respond_to?(:tagged)
logger.tagged(compute_tags(request)) { call_app(request, env) }
else
call_app(request, env)
end
Extracted source (around line #13 ):
11
12
13
14
15
16
::Rails.logger.silence { @app.call(env) }
else
@app.call(env)
end
end
end
Extracted source (around line #81 ):
79
80
81
82
83
84
req = ActionDispatch::Request.new env
req.remote_ip = GetIp.new(req, check_ip, proxies)
@app.call(req.env)
end
# The GetIp class exists as a way to defer processing of the request data
Extracted source (around line #27 ):
25
26
27
28
29
30
req = ActionDispatch::Request.new env
req.request_id = make_request_id(req.x_request_id)
@app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.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 #22 ):
20
21
22
23
24
25
def call(env)
start_time = Utils.clock_time
status, headers, body = @app.call(env)
request_time = Utils.clock_time - start_time
unless headers.has_key?(@header_name)
Extracted source (around line #29 ):
27
28
29
30
31
32
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 #14 ):
12
13
14
15
16
17
state = @executor.run!
begin
response = @app.call(env)
returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
ensure
state.complete! unless returned
Extracted source (around line #127 ):
125
126
127
128
129
130
end
@app.call(req.env)
end
end
end
Extracted source (around line #111 ):
109
110
111
112
113
114
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 #524 ):
522
523
524
525
526
527
def call(env)
req = build_request env
app.call req.env
end
# Defines additional Rack env configuration that is added on each call.
Extracted source (around line #225 ):
223
224
225
226
227
228
def call(env)
env[Const::PUMA_CONFIG] = @config
@app.call(env)
end
end
Extracted source (around line #605 ):
603
604
605
606
607
608
begin
begin
status, headers, res_body = @app.call(env)
return :async if req.hijacked
Extracted source (around line #437 ):
435
436
437
438
439
440
while true
case handle_request(client, buffer)
when false
return
when :async
Extracted source (around line #301 ):
299
300
301
302
303
304
else
if process_now
process_client client, buffer
else
client.set_timeout @first_data_timeout
@reactor.add client
Extracted source (around line #120 ):
118
119
120
121
122
123
begin
block.call(work, *extra)
rescue Exception => e
STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
end
Rails.root: /home/rubys/git/awdwr/edition4/work/depot
Request
Parameters :
{"id"=>"wibble"}
_csrf_token: "Ik0swwjSqEegZDNnoKYWQ7xwe7XTNxccCP4OLt5Ny0c="
cart_id: 1
session_id: "de81ce2ce6a5a9dc4c201a7339c344eb"
GATEWAY_INTERFACE: "CGI/1.2"
HTTP_ACCEPT: "text/html"
HTTP_ACCEPT_ENCODING: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
HTTP_VERSION: "HTTP/1.1"
ORIGINAL_SCRIPT_NAME: ""
REMOTE_ADDR: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"
Response
Headers :
None
10.2 Iteration E2: Handling Errors
9.4 Playtime