[v] xdite rails 第三週開發實作

寄信功能

  • app/views/layout/mailer.text.erb 是做什麼的?

生成 text 格式。也可以是 mailer.html.erb,如此就是生成 html 格式。

  • <%= link_to("訂單連結", order_url(@order.token)) %> 的 url 是什麼?

這邊代表絕對路徑

  • rails mailer

http://guides.rubyonrails.org/action_mailer_basics.html
http://api.rubyonrails.org/classes/ActionMailer/Base.html
https://ihower.tw/rails4/actionmailer.html

  • config.action_mailer.default_url_options = { host: 'localhost:3000' } config.action_mailer.delivery_method = :letter_opener 是怎麼來的?為什麼這樣寫?letter_opener 的 READM.md 沒看到相關內容,要去哪裡找?
  • 拆解 OrderMailer.notify_order_placed(Order.last).deliver!
  • 做什麼?
  • find_by_id(session[:cart_id]) 可以寫成 find_by(id: session[:cart_id]),那 mail(to: @user.email, subject: "blahblahblah") 可不可以寫成 mail_to(@user.email, subject: "blahblahblah") ?

金流功能

  • 'pay2go' gem 是做什麼的?
  • 投影片 "Step 2: 設定整合模式gem"。什麼是"整合模式"?下面整合模式的寫法,是預先定義在 'pay2go' gem 中,還是這是 rails 接 gem 的固定方式?
config.after_initialize do
  Pay2go.integration_mode = :development
end

config.after_initialize do
  Pay2go.integration_mode = :production
end

http://guides.rubyonrails.org/configuring.html 3 Configuring Rails Components
上面找不到 integration_mode 的內容。

  • 沒有 Pay2go class,為什麼可以 Pay2go.integration_mode 或是 Pay2go.setup do |pay2go| 這樣的寫法?
  • pay2go.rb 的位置在 config/initializers/pay2go.rb,這跟前面幾題使用 after_initialize 有關嗎?還是這是智付寶指定要放的位置?
  • 為什麼整合模式寫在 config/environments/development.rb 及 config/environments/production.rb ?
  • config/environments, config/initializers, config/locales......等檔案夾,是 rails 有 convention 指定要放什麼類型的檔案?還是說第三方服務的 API 可以指定放哪裡?如果是後者,那第三方 API 可不可以指定放在新增的檔案夾,比如說 config/pay2go 檔案夾裡面?pay2go_service.rb 放在 app/services/pay2go_service.rb 是 pay2go api 的規定嗎?
  • 上述哪些寫法是 Rails 指定的?哪些是 "pay2go" gem 指定的?哪些是 Pay2go API 指定的?
  • 有哪些功能來自 pay2go api? 哪些來自 pay2go gem?
  • form_tag, hidden_field_tag, submit_tag 各是什麼?

http://stackoverflow.com/questions/7733085/rails-what-exactly-does-hidden-field-and-hidden-field-tag-do

  • callbacks 有什麼用途?這是來自 pay2go 伺服端的回應,還是就只是個我們寫在程式裡的小提示而已?
  • protect_from_forgery

http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html
http://stackoverflow.com/questions/1177863/how-do-i-ignore-the-authenticity-token-for-specific-actions-in-rails

  • 下面 initialize method 是做什麼的?
class Pay2goService

  def initialize(order)
    @order = order
    @timestamp = order.created_at.to_i
    @merchant_order_no = "#{order.id}s#{Time.now.strftime("%Y%m%d%H%M%S")}"
    @total_price = order.total
  end
  ......
  • pay2go_cc_notify_order_url(order.token) 怎麼來的?
  • 在寫 _pay_with_credit_card.html.erb 時,那些掛在 hidden _field _tag 後面的東西是哪裡來的?
  • before_action :authenticate_user!, except: :pay2go_cc_notify 的 except: :pay2go_cc_notify
  • <%= render "pay_with_credit_card", order: @order %> 的 order: @order
  • 為什麼 _pay_with_credit_card 這個 partial 在按下按鈕時能產生用信用卡付款的效果?
  • pay2go_cc_notify method 是什麼時候被執行而能產生 callback 的效果?
  • <%= hidden_field_tag "ReturnURL", pay2go_cc_notify_order_url(order.token) %> 為什麼 pay2go_cc_notify_order_url 後面要套入 order.token 這個參數?
  • if params["Status"] == "SUCCESS" 是 Pay2go API 回傳的資訊嗎? params["status"] 似乎是 hash 結構,這 hash 來自哪裡?怎麼存?

是的,來自Pay2go API,所以沒什麼 local 端怎麼存的問題。

class OrdersController < ApplicationController
......
  def create
  ......
      current_cart.clean!
      OrderMailer.notify_order_placed(Order.last).deliver!
      ......

其中

current_cart.clean!
OrderMailer.notify_order_placed(Order.last).deliver!

這兩行的先後順序有沒有影響到什麼東西?比如說使用者體驗、效能之類的?

Deploy 到 Heroku

  • gem "pg" 是 heroku 指定的 database,並且必須限定在 production 下使用。

  • 4 of 9

Gemfile中

gem 'sqlite3', group: :development

也可以寫成

group: :development do
  gem 'sqlite3'
end

就像該slide下方production的寫法

  • Gemfile 中,production 包在 development, test 這層 scope 內也能運作,但會有什麼影響呢?
group :development, :test do
  gem 'byebug'
  gem 'web-console', '~> 2.0'
  gem 'spring'
  
  group :production do
    gem "pg"
    gem "rails_12factor"
  end
end
  • “因為我們還要測試在 heroku 的刷卡機制,所以先暫時把 production 裡的 pay2go 環境設定改成開發用”。這個修改對於 heroku 端有什麼影響?因為不是說程式部署到 heroku 會自動變成 production 模式嗎?




Deploy 補充 - 環境架構解說

n/a



用 figaro 管理機密資訊

$ figaro install
create  config/application.yml
append  .gitignore

拆解:下了指令後,產生config/application.yml檔,接著把這個檔案加到.gitignore的名單裡面。我們把要用figaro上傳並設定的使用者資料存在config/application.yml檔,因為它已經被加到.gitignore的名單中,所以這些使用者資料不會上傳而被別人看到。接著再透過figaro來把這些使用者資料自動灌上去。

  • 只要有新增、修改帳號密碼,就要跑 figaro heroku:set -e production 將最新的帳號密碼資訊傳到 heroku 去。

  • 什麼是環境變數?

  • application.yml 中的 pay2go_merchant_id: "197----" VS pay2go.rb 中的 pay2go.merchant_id = ENV['pay2go_merchant_id'],這兩種寫法是 conventions 還是 figaro 要求的?

更多開發技巧

  • 為什麼 rake -T 列出的清單中沒有 rake db:reset?

基本收納術

https://rocodev.gitbooks.io/rails-102/content/chapter3-ruby/mixin_extend_inheritance.html

  • 為什麼 tokenable.rb 是放在 app/models/concerns? A.K.A. How to use concerns in Rails 4 ?

https://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns
https://richonrails.com/articles/rails-4-code-concerns-in-active-record-models
http://codefol.io/posts/Where-Do-I-Put-My-Code
http://stackoverflow.com/questions/14541823/how-to-use-concerns-in-rails-4

  • “一般 module 不認識 before_create,用 Rails : Model Concern”。為什麼一般 module 不認識 before_create ? concerns 分多少種?
  • 拆解下方:
module Tokenable
  extend ActiveRecord::Concern

  included do
    before_create :generate_token
  end

  def generate_token
    self.token = SecureRandom.uuid
  end
end

View 收納術

通篇看不懂 =_=

ServiceObject

  • 各個檔案裡的 method 是怎麼被找到的?比如說我們在 app/services/order_placing_service.rb 有一個 OrderPlacingService class,底下有一個叫 place_order! 的 method,然後我們在 app/controllers/orders_controller.rb 裡面用到 OrderPlacingService.new(current_cart, @order).place_order!,請問是怎麼找到的?
  • 可不可以說,service objects 給 controller 用、concerns 給 model 用 partial 給 view 用?helper 在 MVC 三個都可以用?

其他

  • 放 gem 進去 Gemfile 時,實務上會加上版本號嗎?

不一定,看 gem 的 README.md 怎麼寫。但是 ruby 和 rails 的版本好通常是會寫的,因為要讓整個 project 每個人的 ruby 及 rails 版本號是相同的。

  • golden circle: why, how ,what?