Антон Шемерей (Senior Developer в Sphere Consulting, г.Минск)
Доклад: «Single Responsibility Principle в Руби или почему instance/class variables это ОЧЕНЬ плохо»
Всем приходится работать с унаследованным кодом и часами тратить время на поиск устранения ошибок, которых в большинстве случаев можно было бы легко избежать. Одним из краеугольных камней является нарушение принципа единственной ответственности. В докладе пойдет речь о том, как провести анализ кода, как его можно исправить и как избегать таких ошибок в будущем.
3. Dear Anton Shemerey.
Thank you for your patronage. This letter is to confirm that your order from
Doe Books has been filled and should arrive within 15 days.
Shipping books at the book rate generally slows delivery. As you know, payment
in full ($20.75) is due by the end of the month.
Thank you for doing business with Doe. We look forward to serving you again.
If you have questions regarding the new pricing please contact support.
--
Sincerely yours, John Peter
Doe Books
720 S Michigan Ave
Chicago, IL, United States
+1 312-922-4400
Order Confirmation Page
4. Dear. Anton Shemerey
Thank you for your patronage. This letter is to confirm that your order from
Doe Books has been filled and should arrive within 15 days.
Shipping books at the book rate generally slows delivery. As you know, payment
in full ($20.75) is due by the end of the month.
Thank you for doing business with Doe Books. We look forward to serving you again.
If you have questions regarding the new pricing please contact support.
--
Sincerely yours, John Peter
Doe Books
720 S Michigan Ave
Chicago, IL, United States
+1 312-922-4400
Order Confirmation Page variables
5. Dear. {%user_full_name%}
Thank you for your patronage. This letter is to confirm that your order from
{%company_name%} has been filled and should arrive within {%delivery_time%}.
Shipping books at the book rate generally slows delivery. As you know, payment
in full ({%order_total%}) is due by the end of the month.
Thank you for doing business with {%company_name%}. We look forward to serving
you again. If you have questions regarding the {%price_url%} please
contact {%support_email%}.
--
Sincerely yours, {%owner_name%}
{%company_name%}
{%company_address%}
Order Confirmation Template
8. Dear. <%= current_user.full_name %>
Thank you for your patronage. This letter is to confirm that your order from
<%= COMPANY_NAME %> has been filled and should arrive
within <%= @order.estimated_delivery%>.
Shipping books at the book rate generally slows delivery. As you know, payment
in full (<%= number_to_currency(@order.total) %>) is due by the end of the month.
Thank you for doing business with <%= COMPANY_NAME %>. We look forward to
serving you again. If you have questions regarding the <%= @pricing_link %> please
contact <%= email_to(“Support”, $support_email) %>.
--
Sincerely yours, <%= $owner.full_name %>
<%= COMPANY_NAME %>
<%= @@company_address %>
Order Confirmation Template
9. THE Controller :)
class OrdersController < ApplicationController
....
def confirmation
@order = Order.find(params[:id])
end
....
end
10.
11. Dear. <%= current_user.full_name %>
Thank you for your patronage. This letter is to confirm that your order from
<%= COMPANY_NAME %> has been filled and should arrive
within <%= @order.estimated_delivery%>.
Shipping books at the book rate generally slows delivery. As you know, payment
in full (<%= number_to_currency(@order.total) %>) is due by the end of the month.
Thank you for doing business with <%= COMPANY_NAME %>. We look forward to
serving you again. If you have questions regarding the <%= @pricing_link %> please
contact <%= email_to(“Support”, $support_email) %>.
--
Sincerely yours, <%= $owner.full_name %>
<%= COMPANY_NAME %>
<%= @@company_address %>
Order Confirmation Template
12. Dear. <%= @current_user_full_name %>
Thank you for your patronage. This letter is to confirm that your order from
<%= @company_name %> has been filled and should arrive
within <%= @estimated_delivery_time %>.
Shipping books at the book rate generally slows delivery. As you know, payment
in full (<%= number_to_currency(@order_total) %>) is due by the end of the month.
Thank you for doing business with <%= @company_name %>. We look forward to
serving you again. If you have questions
regarding the <%= link_to(‘price’, @pricing_link) %> please
contact <%= email_to(“Support”, @support_email) %>.
--
Sincerely yours, <%= @owner_full_name %>
<%= @company_name %>
<%= @company_address %>
Order Confirmation Template Second Attempt
13. THE Controller :)
class OrdersController < ApplicationController
....
def confirmation
@order = Order.find(params[:id])
@current_user_full_name = current_user.full_name
@company_name = COMPANY_NAME
@estimated_delivery_time = @order.estimated_delivery
@order_total = @order.total
@pricing_link = 'http://example.com/price'
@support_email = 'support@example.com'
@owner_full_name = $owner.full_name
@company_address = @@company_address
end
....
end
Second Attempt
14.
15. Dear. Anton Shemerey
Thank you for your patronage. This letter is to confirm that your order from
Doe Books has been filled and should arrive within 15 days.
Shipping books at the book rate generally slows delivery. As you know, payment
in full ($0) is due by the end of the month.
Thank you for doing business with Doe Books. We look forward to serving you
again. If you have questions regarding the new pricing please contact support.
--
Sincerely yours, John Peter
Doe Books
720 S Michigan Ave
Chicago, IL, United States
+1 312-922-4400
Free Order !!!!
20. Dear. <%= @current_user_full_name %>
Thank you for your patronage. This letter is to confirm that your order from
<%= @company_name %> has been filled and should arrive
within <%= @estimated_delivery_time %>.
Shipping books at the book rate generally slows delivery. As you know, payment
in full (<%= number_to_currency(@order_total) %>) is due by the end of the month.
Thank you for doing business with <%= @company_name %>. We look forward to
serving you again. If you have questions
regarding the <%= link_to(‘price’, @pricing_link) %> please
contact <%= email_to(“Support”, @support_email) %>.
--
Sincerely yours, <%= @owner_full_name %>
<%= @company_name %>
<%= @company_address %>
Order Confirmation Template binding.pry
<%- require 'pry'; binding.pry %>
23. How are rails instance
variables passed to views
?????
24. AbstractController::Rendering#view_assigns
module AbstractController
module Rendering
# ....
# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
# :api: public
def view_assigns
protected_vars = _protected_ivars
variables = instance_variables
variables.reject! { |s| protected_vars.include? s }
variables.each_with_object({}) { |name, hash|
hash[name.slice(1, name.length)] = instance_variable_get(name)
}
end
# ....
end
end
27. GREP!!!
$ grep -iRn @order_total app/helpers | wc
#=> 2 8 143
Second Attempt
module ApplicationHelper
....
def current_cart_total
if current_user
if order = current_user.current_order
@order_total = order.total
end
else
@order_total = Money.new(0)
end
end
....
end
28. $ git blame | grep current_cart_total
Problem Fixed!
29. class OrdersController < ApplicationController
before_action :load_order, only: [:show, :update, :destroy]
def update
if @order.update_attributes(params[:order])
redirect_to :show
else
render 'edit'
end
end
private
def load_order
@order = Order.find(params[:id])
end
end
Controller.before_action
30. class OrdersController < ApplicationController
....
def order
@order ||= Order.find(params[:id])
end
....
end
Memoization
31. class OrdersController < ApplicationController
helper_method :order
def update
if order.update_attributes(params[:order])
redirect_to :show
else
render 'edit'
end
end
private
def order
@_order ||= Order.find(params[:id])
end
end
Controller.helper_method