前言
當我們在寫專案時,有很多的功能會寫在各自的 MVC 裡。
但當這項功能是 CRUD 以外的功能,我們究竟要把它寫在哪呢?
Service
通常這類功能,像是金流串接,需要將參數加密後發 request 到金流廠商,接著再接收金流廠商發過來的 request 並解碼,再回傳相關資料。
這樣的 code 寫在哪比較合理?
看起來 model 是一個選項,但你要選擇哪個 model? 新增一個 model 來做這件事情似乎也有點奇怪。
所以我們可以把這類的功能整理到 app/service/payment 裡。
也就是在 app 底下新增 service 與 payment 資料夾,並在底下建立 xxxx.rb,並在這建立一個 PORO 底下則開始寫功能的 code:
(以下為串接綠界金流的 code )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| module Payment class EcpayRequest require 'uri' require 'openssl' require 'CGI' def initialize(merchant_trade_date, merchant_trade_no, title, pirce) @params = { "TradeDesc": "專案贊助交易", "PaymentType": "aio", "MerchantTradeDate": merchant_trade_date, "MerchantTradeNo": merchant_trade_no, "MerchantID": 3002607, "ReturnURL": "https://f25a-103-3-192-33.jp.ngrok.io/payment/returnpage", "ItemName": title "TotalAmount": price, "ChoosePayment": "ALL", "IgnorePayment": "WebATM#ATM#CVS#BARCODE", "EncryptType": 1 } end def perform(params) encrypt(params) end private def encrypt(params) order_query_string = URI.encode_www_form(params.to_a.sort!) key_vi = "HashKey=pwFHCqoQZGmho4w6&" + order_query_string + "&HashIV=EkRm7iFT261dpevs" url_encode = (CGI.escape key_vi).downcase.gsub!(/%25/, '%').gsub!(/%2b/, '+') encrypted_result = Digest::SHA256.hexdigest(url_encode).upcase end def request end end end
|
這時就可以使用類別來做事:
沒意外,這時會顯示 找不到常數 Payment::EcpayRequest 的錯誤。
解決辦法
會出現該訊息是因為,Rails 抓不到這個 class,所以要把 config/application.rb 大概第 21 行程式碼打開:
1
| config.eager_load_paths << Rails.root.join("extras")
|
這樣 Rails 在 load 的時候,就會抓到了。