最近幾乎所有的web應(yīng)用里面存在用戶上傳文件的需求,
可能是一個(gè)個(gè)性的頭像,一個(gè)要賣(mài)的商品圖片或者一些分類的文檔。
在過(guò)去的一些年里,我們幾乎都在用carrierwave或者paperclip去處理Rails的上傳,現(xiàn)在在5.2版本里面我們有另外一種方式:ActiveStorage。
什么是Active Storage?
來(lái)自他的說(shuō)明文檔:
Active Storage 讓上傳更簡(jiǎn)單,通過(guò)云服務(wù)應(yīng)用文件如:Amazon S3, Google Cloud Storage or Microsoft Azure Storage,而且attach這些文件到ActiveRecords。支持一個(gè)主要服務(wù)和鏡像在別的服務(wù)redundancy,他也提供磁盤(pán)服務(wù)for testing或者本地開(kāi)發(fā),但是他重點(diǎn)在于云存儲(chǔ)。
ActiveStorage 是一個(gè)幫助你處理文件上傳的引擎,in yourRailsApps in a very straightforward and? ?easy way.
Set it up
讓我們來(lái)創(chuàng)建一個(gè)rails app示例,我現(xiàn)在假設(shè)你已經(jīng)安裝了rails5.2.
rails new catalog
在你開(kāi)始使用ActiveStorage前,你需要一個(gè)數(shù)據(jù)庫(kù)表,運(yùn)行下面的命令安裝數(shù)據(jù)庫(kù)遷移:
bin/rails active_storage:install
現(xiàn)在你創(chuàng)建產(chǎn)品model通過(guò)titlle,然后運(yùn)行所有的migrations
```
bin/rails generate scaffold products title:string?
bin/rails db:migrate
```
附加一個(gè)文件到model
現(xiàn)在,我們假設(shè)我們每個(gè) Product對(duì)象都有一個(gè)picture。我們通過(guò)has_one_attached 方法去定義這個(gè)關(guān)系。
class Product < AppicationRecord
? has_one_attached :picture
end
我們現(xiàn)在需要在Product定義一個(gè)字段,用戶能夠去指定這個(gè)要上傳的文件。編輯app/views/products/_form.html.erb找到field定義位置,增加下面的代碼:
<div class="field">
<%=form.lavel :title >
<%= form.text_field :title %>
</div>
<!--Add this-->
<div class="field">
<%= form.label :picture %>
<%= form.file_field :picture %>
</div>
<div class="action">
<%= form.submit %>
</div>
還需要在ProductController里面增加‘picture'到運(yùn)行的參數(shù)。
def product_params
? params.require(:product).permit(:title, :picture)
end
現(xiàn)在如果你啟動(dòng)服務(wù),導(dǎo)航到/products, 點(diǎn)擊’新增‘,輸入標(biāo)題和選擇一個(gè)圖片,你會(huì)在development.log里面看到通知:INSERT statement to the active_storate_blobs 表。
找到一些相識(shí)的日志如:
ActiveStorage::Attachment Create(0.3ms) INSERT INTO "active_Storage_attachments"("name","record_type","blob_id", "created_at") VALUES(?,?,?,?)[["name","picture"]["record_type", "Product"],["record_id", 4],{"bolb_id", 2],["created_at", "2018......."]]
顯示附件
你可以通過(guò)調(diào)用url_for helper 返回這個(gè)附件的url,在我們的案例中在上傳完成后顯示。編輯app/views/products/index.html.erb,增加下面代碼:
<tbody>
<td>..</td>
<td><%=image_tag url_for(product.picture)%></td>
你的scaffold會(huì)在你上傳后顯示這個(gè)圖片。
不同的Storage Stragegies
當(dāng)你在開(kāi)發(fā)環(huán)境俠士,你想保持上傳文件在你本地磁盤(pán),但是當(dāng)你發(fā)布時(shí)你想使用第三方服務(wù)去存儲(chǔ)他們,比如Amaon S3,Azure Storage Service 或者Google Cloud Storage。
使用ActiveStorage處理這個(gè)非常方便。
在config/storage.yml里面聲明不同的環(huán)境存儲(chǔ)配置。比如:local環(huán)境聲明’disk‘,生產(chǎn)環(huán)境’amazon'
local:
? service: Disk
? root: <%= Rails.root.join("storage")%>
amazon:
? service: S3
? access_key_id: AMAZONE KEY
? secret_access_key: AMAZON SECRET KEY
然后,在對(duì)應(yīng)的config/environments/*.rb文件里面知道storage來(lái)使用。
比如:development.rb
config.active_storate.service = :local
production.rb
config.active_storage.service = :amazon
說(shuō)明:你可能需要包含額外的gem包,在Gemfile里面,要使用Amazon S3你需要包含aws-sdk-s3
gem "aws-sdk-s3", require: false
更多的功能特點(diǎn)
ActiveStorage還有很多功能,參考官方文檔。