想問問建議 Rails 中 ActionDispatch::Request 之問題


#1

小弟正在寫的 API 專案有遇到要將圖片的全網址傳過去給對方!

於是使用了 request.host 與 port,而片段程式碼成如下:

...
"http://#{request.host}:#{request.port}#{photo.photo.url(:small)}"
...

剛開始單純在 Controller 端可行,後來想說將資料隱藏在 Model 端,於是做些加工後變成…

# models
def self.handle_data(request,photo)
return  {
    id: photo.id,
    title: photo.title,
    photos: "http://#{request.host}:#{request.port}#{photo.photo.url(:small)}"
}
end

最後又想說每次都要打的東西想放在 concerns 共用

# models/concerns/default_url.rb
module DefaultUrl
  def photo_url(request,photo)
    return "http://#{request.host}:#{request.port}#{photo}"
  end
end

# models
def self.handle_data(request,photo)
return  {
    id: photo.id,
    title: photo.title,
    photos: photo_url(request,photo.photo.url(:small))
}
end

然後發現 request 從 Controller > Model > Concerns 的 module 了…
而似乎 request 好像不能在 Model 直接被使用,會得到 undefined 這個詞

# models
puts request.host   # NameError (undefined local variable or method `request' for #< ... >

想來問問說 怎麼簡化以上這個寫法!!

感恩~


#2

… 為何你會想在 model 內處理 view 的東西 … 寫在 controller 內包裹不好嗎?

class ApplicationController < ActionController::Base
  helper_method :pack_public_url
  def pack_public_url(sub_path)
    return "http://#{request.host}:#{request.port}#{sub_path}"
  end
end

#使用( controller / view )
pack_public_url(photo.photo.url(:small))

當然如果你的 API 是用 grape 打的就要另外寫一份了( grape 有自己的規則 … ),原因, controller 和 view 都能取到當下 session 的 request … model 層還要另外餵進去唄||| 既然下一步都是出門了,為何還要往底層走一遭哩|||

倒是另外一方面,其實我不會用 request.host 這種寫法啦,因為 online 後應該有設定值可以抓到漂亮點的網址才是(不含 port),否則你掛 proxy 甚至 LB 幫加解 SSL 會掛光光唄|||


#3

會想這樣寫是因為 這邊小弟是有聽過一個說法 就是將 “商業邏輯端 隱藏在 model 內”。
因此才會想說 在 model 端,寫好 資料搜尋 及 處理要 response 的資料,在 controller 端,只要接收並 render 資料 出去這樣。

另外若不使用 request 這個類別,那怎麼傳正確的圖片網址給對方吶??


#4

簡單的會類似這樣唄

if Rails.env == 'development'
  return "http://#{request.host}:#{request.port}#{sub_path}"
else
  return "http://example.com#{sub_path}"
end

& 你知道啥是 … 『商業邏輯』嗎?粗淺的定義其實是一連串有關於 transaction 的動作,類似

使用者買了一張票,要扣使用者 10 元,還有給他一張票
必須保證使用者能扣到10元,且會增加一張票
如果沒有票,或使用者不足10元,則不能進行此交易

這叫 transaction ,其實這個詞應該是從資料庫來的,類似 ACID


所以你認為顯示給使用者的資訊的包裹,屬於商業邏輯嗎?


#5

哦! 了解… 本以為 商業邏輯端包含對資料庫的處理程序外還給使用者的資料包裹,因此才會想這樣做!
看來 我好像搞錯了…! 才導致寫法那麼的奇怪!! 感恩感恩,我會再對商業邏輯端去做些加強的!