November 01, 2022
380

# 2022 - 默默會 - 重新學習 MVC 的 Model

## 蒼時弦や

November 01, 2022

## Transcript

3. ### Coding Happier About Me Senior 60% +10% Junior 18% +3%

Junior 18% +3% Avg - 37% VS Senior 60% +3% Junior 18% +15% Junior 18% +15% Avg - 43%
4. ### What we talk about Overview What is Model What is

Model How to Modeling Case Study
5. ### What we talk about Overview What is Model How to

Modeling How to Modeling Case Study
6. ### What we talk about Overview What is Model How to

Modeling Case Study Case Study
7. ### What is Model The Model What is Model Anyone have

can sharing about it?
8. ### What is Model The Model Float 100.0 String TWD VS

Money TWD \$100.0
9. ### What is Model The Model Information A model is an

informative representation of an object, person or system.
10. ### What is Model The Model Float 100.0 String TWD VS

Money TWD \$100.0 Which one can “Pay” Pay

12. ### Value Object Modeling Data Amount=100.0 + Data Currency=TWD Value Composite

Value Money=TWD,100.0
13. ### Value Object Modeling class Money attr_reader :currency, :amount def initialize(currency,

amount) @currency = currency @amount = amount end end
14. ### Entity Modeling Value ID=1 + Value Money<TWD, 100.0> Entity Composite

Entity ID=1, Balance=Money<TWD, 100.0>
15. ### Entity Modeling class Wallet attr_reader :id, :balance def initialize(id, balance)

@id = id @balance = balance end end
16. ### Method Modeling Entity ID=1, Balance=Money<TWD, 100.0> Deposit(Money<TWD, 100.0>) Entity ID=1,

Balance=Money<TWD, 200.0>
17. ### Entity Modeling class Wallet attr_reader :id, :balance def initialize(id, balance)

@id = id @balance = balance end end sig { params(amount: Money).returns(Money) } def deposit(amount) @balance += amount end
18. ### The Payment App Case Study The Payment App The usage

of “Model” in the real-world
19. ### Analytics Case Study Customer Pay Command Transfer to Merchant System

Paid Event Failed Event
20. ### Analytics Case Study Customer Pay Command Transfer to Merchant System

Paid Event Failed Event Given threre have a customer “Aotoki” And I logged as “Aotoki”
21. ### Analytics Case Study Customer Pay Command Transfer to Merchant System

Paid Event Failed Event When I pay for the merchant “FamilyMart”
22. ### Analytics Case Study Customer Pay Command Transfer to Merchant System

Paid Event Failed Event Then I can see “Pay for FaimlyMart successful”
23. ### Analytics Case Study Customer Pay Command Transfer to Merchant System

Paid Event Failed Event Then I can see “Pay for FaimlyMart failed”
24. ### Specs Case Study Feature: Scenario: Given And And When Then

Payment Pay to the merchant there have a custoemr there have a merchant I logged as I pay for the merchant I can see “Aotoki” “FamilyMart” “Aotoki” “FamilyMart” “Pay for FamilyMart successful”
25. ### Specs Case Study RSpec.describe do describe subject before do end

it is_expected to have_text end end , type: :request do { post payment_path, } customer = create(:customer, ) sign_in customer create(:merchant, ) { . ( ) } ‘Payment’ ‘POST /payment’ merchant_id: ‘fmart’, amount: 100 name: ‘Aotoki’, balance: 100 id: ‘fmart’ ‘Pay for FamilyMart successful’
26. ### Specs Case Study RSpec.describe do describe subject it is_expected to

have_text end end , type: :request do { post payment_path, } { . ( ) } ‘Payment’ ‘POST /payment’ merchant_id: ‘fmart’, amount: 100 ‘Pay for FamilyMart successful’
27. ### Example Code Case Study def create render text: ‘Pay for

FamilyMart successful’ end
28. ### Example Code Case Study class Merchant include ActiveModel::Model include ActiveModel::Attributes

attribute :name, :string alias_attribute :to_s, :name end
29. ### Example Code Case Study def create render text: end merchant

= Merchant.new(name: ‘FamilyMart’) “Pay for #{merchant} successful”
30. ### Example Code Case Study class Customer include ActiveModel::Model include ActiveModel::Attributes

attribute :name, :string attribute :balance, :integer def withdraw(amount) raise ArgumentError, ‘insufficient balance’ if amount > self.balance self.balance -= amount end end
31. ### Example Code Case Study class Merchant include ActiveModel::Model include ActiveModel::Attributes

attribute :name, :string alias_attribute :to_s, :name end attribute :balance, :integer def deposit(amount) self.balance += amount end
32. ### Example Code Case Study def create merchant = Merchant.new(name: ‘FamilyMart’)

render text: “Pay for #{merchant} successful” end customer = Customer.new(name: ‘Aotoki’, balance: 100) payment_amount = params.require(:amount) customer.withdraw(payment_amount) merchant.deposit(payment_amount)
33. ### Example Code Case Study class Merchant def deposit(amount) self.balance +=

amount end end < ApplicationRecord
34. ### Example Code Case Study class Customer def withdraw(amount) raise ArgumentError,

‘insufficient balance’ if amount > self.balance self.balance -= amount end end < ApplicationRecord
35. ### Example Code Case Study def create payment_amount = params.require(:amount) merchant.deposit(payment_amount)

render text: “Pay for #{merchant} successful” end merchant = Merchant.find_by!(id: params[:merchant_id]) current_customer.withdraw(payment_amount) ActiveRecord::Base.transaction do merchant.save! current_customer.save! end
36. ### Example Code Case Study def create merchant = Merchant.find_by!(id: params[:merchant_id])

payment_amount = params.require(:amount) current_customer.withdraw(payment_amount) merchant.deposit(payment_amount) ActiveRecord::Base.transaction do merchant.save! current_customer.save! end render text: “Pay for #{merchant} successful” end rescue ActiveRecord::RecordInvalid render text: “Pay for #{merchant} failed”
37. ### Example Code Case Study class Money include ActiveModel::Model include ActiveModel::Attributes

attribute :value, :integer def +(other) Money.new(value: self.value + other.value) end def -(other) raise ArgumentError, ‘Money cannot be negative’ if other.value > self.value Money.new(value: self.value - other.value) end end
38. ### Example Code Case Study class Merchant < ApplicationRecord def deposit(amount)

self.balance += amount end end composed_of :balance, class_name: ‘Money’, mapping: %[balance value]
39. ### Example Code Case Study class Customer < ApplicationRecord def withdraw(amount)

self.balance -= amount end end composed_of :balance, class_name: ‘Money’, mapping: %[balance value]
40. ### Example Code Case Study def create merchant = Merchant.find_by(id: params[:merchant_id])

current_customer.withdraw(payment_amount) merchant.deposit(payment_amount) ActiveRecord::Base.transaction do merchant.save! current_customer.save! end render text: “Pay for #{merchant} successful” rescue ActiveRecord::RecordInvalid render text: “Pay for #{merchant} failed” end payment_amount = Money.new(value: params.require(:amount))
41. ### Example Code Case Study def create merchant = Merchant.new(name: ‘FamilyMart’)

ActiveRecord::Base.transaction do merchant.save! current_customer.save! end render text: “Pay for #{merchant} successful” rescue ActiveRecord::RecordInvalid render text: “Pay for #{merchant} failed” end context = BuyingContext.new input = PaymentInput.new(params) context.pay(to: merchant, from: current_customer, amount: input.amount)