Slide 1

Slide 1 text

Rails Developer Foundation ver.Open Learn Model Again

Slide 2

Slide 2 text

CONSULTANT × SPEAKER 蒼時弦也 YouTube Coding Live Blog https://blog.aotoki.me Discord Discuss about Ruby Introduce About Me

Slide 3

Slide 3 text

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%

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

What is Model The Model What is Model Anyone have can sharing about it?

Slide 8

Slide 8 text

What is Model The Model Float 100.0 String TWD VS Money TWD $100.0

Slide 9

Slide 9 text

What is Model The Model Information A model is an informative representation of an object, person or system.

Slide 10

Slide 10 text

What is Model The Model Float 100.0 String TWD VS Money TWD $100.0 Which one can “Pay” Pay

Slide 11

Slide 11 text

How to Modeling Modeling Modeling How to "modeling"

Slide 12

Slide 12 text

Value Object Modeling Data Amount=100.0 + Data Currency=TWD Value Composite Value Money=TWD,100.0

Slide 13

Slide 13 text

Value Object Modeling class Money attr_reader :currency, :amount def initialize(currency, amount) @currency = currency @amount = amount end end

Slide 14

Slide 14 text

Entity Modeling Value ID=1 + Value Money Entity Composite Entity ID=1, Balance=Money

Slide 15

Slide 15 text

Entity Modeling class Wallet attr_reader :id, :balance def initialize(id, balance) @id = id @balance = balance end end

Slide 16

Slide 16 text

Method Modeling Entity ID=1, Balance=Money Deposit(Money) Entity ID=1, Balance=Money

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

The Payment App Case Study The Payment App The usage of “Model” in the real-world

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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”

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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”

Slide 25

Slide 25 text

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’

Slide 26

Slide 26 text

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’

Slide 27

Slide 27 text

Example Code Case Study def create render text: ‘Pay for FamilyMart successful’ end

Slide 28

Slide 28 text

Example Code Case Study class Merchant include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string alias_attribute :to_s, :name end

Slide 29

Slide 29 text

Example Code Case Study def create render text: end merchant = Merchant.new(name: ‘FamilyMart’) “Pay for #{merchant} successful”

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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)

Slide 33

Slide 33 text

Example Code Case Study class Merchant def deposit(amount) self.balance += amount end end < ApplicationRecord

Slide 34

Slide 34 text

Example Code Case Study class Customer def withdraw(amount) raise ArgumentError, ‘insufficient balance’ if amount > self.balance self.balance -= amount end end < ApplicationRecord

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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”

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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))

Slide 41

Slide 41 text

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)

Slide 42

Slide 42 text

Survey Feedback Survey https://www.surveycake.com/s/lbmn9