holi

Subtitle

¿Quiénes somos?

Licenciado en Física de La UD

Ingeniero de La UD

%h4
  = "Valor en pesos: #{@book.value}"
%h4
  = "Valor en dolares: "
%h4
  = number_to_currency(CurrencyService.exchange_to(@book.value, 'COP', 'USD'), unit:'USD'):

emm...funciona...

Sin embargo...

Presenters

  • Clase
  • Patrón Decorador
  • Libera la vista de lógica
%h4
  = "Valor en pesos: #{@book.value}"
%h4
  = "Valor en dolares: #{@book.value_in_usd}"

Excelente!

class BookPresenter < BasePresenter
  def value_in_usd
    number_to_currency(CurrencyService.exchange_to(value, 'COP', 'USD'), unit:'USD') 
  end
end

¿Que tal?

class BasePresenter < SimpleDelegator
 include ActionView::Helpers
 attr_reader :source

 def initialize(source)
   @source = source
   super(source)
 end
end

Rutas

Mantener el estandar RESTFUL

SocialTarget::Application.routes.draw do
  resources :books, only: [:show]
end

Esto se puede mejorar así:

SocialTarget::Application.routes.draw do 
  namespace :book do 
    get 'show_book/:book_id' => 'books/books#show_book' 
  end 
end 

Controladores

Acepta peticiones HTTP y devuelve una respuesta

class BooksController < ApplicationController
  def show_book
    @book = Book.where(id: params['book']['id']).last
  end

  def save_book
    @book = Book.where(id: params['book']['id']).last
    @book.author = params['book']['author']
    @book.more_data = params['book']['more_data']
    @book.more_data_2 = params['book']['more_data_2']
    @book.value = params['book']['value']
    @book.pages = params['book']['pages']
    @book.price_per_page = @book.value / @book.pages
    @book.taxes = @book.value * 0.16
    @book.save
    redirect_to "/show_book/#{@book.id}"
  end
end
class BooksController < ApplicationController
  def show
    @book = Book.find(params['id'])
  end
  def update
    @book = Book.find(params['book']['id'])
    updater = BookUpdater.new(@book, params['book'])
    if updater.update_data("price")
      flash[:success]
    else
      flash[:error]
    end
    redirect_to book_path(@book)
  end
end
class BookUpdater
  def initialize(book, data)
    @book = book
    @data = data
  end
    
  def update_data
    @data['price_per_page'] = @book.value / @book.pages
    @data['taxes'] = @book.value * 0.16
    @book.update_attributes(@data)
  end
end

La lógica pasa a una librería

Módulos

Un módulo es una colección de métodos y constantes.

Namespaces

Mixins

No state dependent

Namespaces

module Trig
  PI = 3.141592654
  def Trig.sin(x)
   # ..
  end
  def Trig.cos(x)
   # ..
  end
end
module Action
  VERY_BAD = 0
  BAD      = 1
  def Action.sin(badness)
    # ...
  end
end
y = Trig.sin(Trig::PI/4)
wrongdoing = Action.sin(Action::VERY_BAD)

Mixins

Herencia Múltiple ?

Evitar la Duplicación de Lógica

module Debug
  def whoAmI?
    "#{self.type.name} (\##{self.id}): #{self.to_s}"
  end
end

class Phonograph
  include Debug
  # ...
end

class EightTrack
  include Debug
  # ...
end

ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? → "Phonograph (#537766170): West End Blues"
et.whoAmI? → "EightTrack (#537765860): Surrealistic Pillow"

No State Dependent

class API

  def fetch(id)
    HTTP.get('http://matt.aimonetti.net/article/:id', :id => id)
  end

end


resource = API.new.fetch(42)
module API

  def self.fetch(id)
    HTTP.get('http://matt.aimonetti.net/article/:id', :id => id)
  end

end

resource = API.fetch(4)

Uso de Módulos en Modelos

class Post < ActiveRecord::Base
  validates :title, :content, presence: true

  has_many :votes
  has_many :comments

  def vote!
    votes.create
  end
end

class Comment < ActiveRecord::Base
  validates :content, presence: :true

  belongs_to :post
end

class Vote < ActiveRecord::Base
  belongs_to :post
end

Hasta ahora todo va bien

Uso de Módulos en Modelos

class Post < ActiveRecord::Base
  validates :title, :content, presence: true

  has_many :votes, as: :votable
  has_many :comments

  def vote!
    votes.create
  end
end

class Comment < ActiveRecord::Base
  validates :content, presence: :true

  has_many :votes, as: :votable
  belongs_to :post

  def vote!
    votes.create
   end
end

class Vote < ActiveRecord::Base
  belongs_to :votable, polymorphic: true
end

Uso de Módulos en Modelos

class Vote < ActiveRecord::Base
  enum type: [:upvote, :downvote]

  validates :type, presence: true

  belongs_to :votable, polymorphic: true
end

Uso de Módulos en Modelos

module Votable
  extend ActiveModel::Concern

  included do
    has_many :votes, as: :votable
  end

  def upvote!
    votes.create(type: :upvote)
  end

  def downvote!
    votes.create(type: :downvote)
  end
end
class Post < ActiveRecord::Base
  include Votable

  validates :title, :content, presence: true

  has_many :comments
end

class Comment < ActiveRecord::Base
  include Votable

  validates :content, presence: :true

  belongs_to :post
end

¿Preguntas?

Gracias!

Made with Slides.com