Антон Шемерей «Single responsibility principle в руби или почему...
-
Upload
- -
Category
Technology
-
view
298 -
download
1
Transcript of Антон Шемерей «Single responsibility principle в руби или почему...
Anton Shemerey@shemerey
Single Responsibility Principle в Руби или почему instance/class variables это ОЧЕНЬ плохо
each object should have one and
only one responsibility
Dear Anton Shemerey.
Thank you for your patronage. This letter is to confirm that your order fromDoe Books has been filled and should arrive within 15 days.
Shipping books at the book rate generally slows delivery. As you know, paymentin 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 PeterDoe Books
720 S Michigan AveChicago, IL, United States+1 312-922-4400
Order Confirmation Page
Dear. Anton Shemerey
Thank you for your patronage. This letter is to confirm that your order fromDoe Books has been filled and should arrive within 15 days.
Shipping books at the book rate generally slows delivery. As you know, paymentin 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 PeterDoe Books
720 S Michigan AveChicago, IL, United States+1 312-922-4400
Order Confirmation Page variables
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, paymentin 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
Data we have :(
• current_user.full_name #=> ‘Anton Shemerey’
• @order.estimated_delivery #=> ’15 days’
• @order.total #=> ‘<Money: @cents = 2075 ….’
• COMPANY_NAME #=> ‘Doe Books’
• $owner.full_name #=> ‘John Peter’
• @pricing_link #=> ‘http://example.com/price'
• $support_email = ‘[email protected]’
• @@company_address #=> ‘720 S Michigan Ave Chicago….’
Facepalm
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, paymentin 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
THE Controller :)
class OrdersController < ApplicationController .... def confirmation @order = Order.find(params[:id]) end ....end
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, paymentin 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
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, paymentin 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
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 = '[email protected]' @owner_full_name = $owner.full_name @company_address = @@company_address end ....end
Second Attempt
Dear. Anton Shemerey
Thank you for your patronage. This letter is to confirm that your order fromDoe Books has been filled and should arrive within 15 days.
Shipping books at the book rate generally slows delivery. As you know, paymentin 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 PeterDoe Books
720 S Michigan AveChicago, IL, United States+1 312-922-4400
Free Order !!!!
Five sec to fix ;-)
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 = '[email protected]' @owner_full_name = $owner.full_name @company_address = @@company_address end # ....end
binding.pry
require 'pry'; binding.pry
2.0.0-p353 :006 > @order_total => #<Money:0x007fc7afb23530 @cents=83991, @currency="USD", @bank=#<Money::VariableExchangeBank:0x007fc7a36415c8 @rates={}, @mutex=#<Mutex:0x007fc7a3641528>>>
WTF ?!?!?!?!
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, paymentin 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 %>
2.0.0-p353 :0016 > @order_total => #<Money:0x007fc7afb23530 @cents=0, @currency="USD", @bank=#<Money::VariableExchangeBank:0x007fc7a36415c8 @rates={}, @mutex=#<Mutex:0x007fc7a3641528>>>
WTF ?!?!?!?!
GREP!!!
$ grep -iRn @order_total app | wc
#=> 151 1017 17348
How are rails instance variables passed to
views?????
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 # .... endend
module AbstractController def view_context view_context_class.new(
view_renderer, view_assigns, self) endend
AbstractController#view_context
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
$ git blame | grep current_cart_total
Problem Fixed!
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]) endend
Controller.before_action
class OrdersController < ApplicationController .... def order @order ||= Order.find(params[:id]) end ....end
Memoization
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]) endend
Controller.helper_method
• memoization / lazy loading
• encapsulating (getter, setter)
• barewords (method, local variable, helper_method, ….)
#source_location, caller
def total_order stack = caller require 'pry'; binding.pry ...end
<% self.method(:total_order).source_location %>
one action one @
• PRESENTER
• SERVICE OBJECT
• PROXY OBJECT
• VALUE OBJECT
• LOCALS
• HELPER_METHOD
You can always use following
#destroy_all_view_assigns
group :development, :test do gem 'destroy_all_view_assigns'end
https://github.com/shemerey/destroy_all_view_assigns
https://github.com/shemerey
https://www.facebook.com/shemerey
https://twitter.com/shemerey
https://www.linkedin.com/in/shemerey
Questions ???