亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Web服務器 > 正文

如何使用 Rails 和七牛云存儲,在 15 分鐘內打造一個圖片分享社交應用原型

2024-09-01 13:47:45
字體:
來源:轉載
供稿:網友
今天,就讓我們一起來看看如何使用 Rails 和七牛云存儲,在 15 分鐘內打造一個圖片分享社交應用原型
 

 

十年前,Web 應用框架 Rails 創始人 David Heinemeier Hansson 曾錄制視頻,向我們演示如何使用 Ruby on Rails 在 15 分鐘內創作一個 blog 引擎。這個視頻通過 Rails 優秀的 MVC 、習慣優于配置(Convention over Configuration)等設計,以及強大的代碼生成、scaffold 等功能,成功展示了 Ruby on Rails 編寫 Web 應用核心功能的高效簡潔。Ruby on Rails 這門技術也在 Web 2.0 時代大放異彩,成為了 Web 應用開發最佳的技術方案選擇之一。

經過十年的發展,軟件行業早已邁入云計算時代。為了應對大規模的訪問量,同時控制研發和運營成本,作為云計算基石的云存儲,已經成為了 Web 開發必不可少的基礎設施。今天,就讓我們一起來看看如何使用 Rails 和七牛云存儲,在 15 分鐘內打造一個圖片分享社交應用原型。

七牛云存儲 是一個公有云服務,提供海量對象存儲功能,以及云端文件處理和分發服務。開始之前,我們需要創建一個七牛云存儲 試用帳戶,并且了解一些基礎知識:

七牛云存儲是一個 Key-Value 形式的對象存儲系統,一個 key 對應一個資源(文件)。
資源必須存儲在某個空間(Bucket)中,不可單獨存在。一個帳戶可以創建多個空間。

創建基本 Rails 項目

你應該可以使用 Ruby 1.9 以上,Rails 3.0 以上的任意版本,本例中我們使用的是 Ruby 2.2.3 和 Rails 4.2.5。

安裝好 Ruby 和 Rails 之后,使用 rails 命令創建應用程序 konata 的目錄結構和基本文件:

 

復制代碼代碼如下:

rails new konata

稍候這條命令執行完成,我們立即得到了一個可以運行的空白 Rails 應用程序,執行以下命令,并在瀏覽器中訪問 http://localhost:3000 查看運行效果:

 

 

復制代碼代碼如下:

cd konata
rails server

 

使用 Rails Scaffold 實現 CRUD

我們將使用 Rails 的 scaffold 功能,生成用于處理圖片發表的 model、controller、view,以及 database migration 等源代碼文件。

 

復制代碼代碼如下:

rails generate scaffold post title filename qiniu_hash
rake db:migrate

訪問 http://localhost:3000/posts 可以看到,我們已經獲得了 post 的完整 CRUD 功能,只是暫時還不能上傳圖片。

 

使用七牛 API 實現圖片上傳

修改 Gemfile,在其中加入對七牛 Ruby SDK 的引用:

 

復制代碼代碼如下:

gem 'qiniu'

 

執行以下命令安裝七牛 Ruby SDK。這里原本應該執行 bundle 進行安裝,但由于七牛 Ruby SDK 依賴的 mime-types 版本設定比較保守,需要使用 bundle update 命令降級 mime-types,解決依賴沖突。

 

復制代碼代碼如下:

bundle update mime-types

 

編輯 config/secrets.yml,在其中加入七牛云存儲帳戶的密鑰:

 

復制代碼代碼如下:

development:
secret_key_base: <YOUR_SECRET_KEY_BASE>
qiniu_access_key: <YOUR_QINIU_ACCESS_KEY>
qiniu_secret_key: <YOUR_QINIU_SECRET_KEY>

 

創建 config/initializers/qiniu.rb,使用剛才加入的密鑰與七牛云存儲服務器建立連接。內容如下:

require 'qiniu'Qiniu.establish_connection!( access_key: Rails.application.secrets.qiniu_access_key, secret_key: Rails.application.secrets.qiniu_secret_key)

注意:

AccessKey 和 SecretKey 必須絕對保密,不可出現在用戶可以查看的 Web 前端源代碼里,或是編譯進客戶端二進制代碼中。

七牛 API 提供了多種上傳方式 以滿足不同的業務場景需求。這里我們選擇使用最有代表性,也最簡單的 HTML 表單上傳+HTTP 303 重定向返回的方式實現客戶端文件直接上傳七牛云存儲。這種方法的好處是客戶端文件無需通過業務服務器(app server)中轉,既可以利用七牛強大的 CDN 優化上傳速度及提高可靠性,也可以節省業務服務器帶寬。

編輯 app/views/posts/_form.html.erb,根據七牛云存儲 SDK 構造上傳表單。注意其中的上傳憑證字段,我們將在 PostsController 里創建它:

<%= form_tag 'http://upload.qiniu.com', multipart: true do %> <%= hidden_field_tag :token, @qiniu_upload_token %> <div class="field"> <%= label_tag :title %><br> <%= text_field_tag 'x:title' %> </div> <div class="field"> <%= label_tag :image %><br> <%= file_field_tag :file %> </div> <div class="actions"> <%= submit_tag 'Create' %> </div><% end %>

編輯 app/controllers/posts_controller.rb,添加代碼生成上傳憑證,以及根據七牛云存儲自定義響應內容創建 post 實例:

def new @qiniu_upload_token = generate_qiniu_upload_token @post = Post.new end def create upload_ret = JSON.parse(Base64.urlsafe_decode64(params[:upload_ret])) @post = Post.new( title: upload_ret['title'], filename: upload_ret['fname'], qiniu_hash: upload_ret['hash'] ) # ... end private def generate_qiniu_upload_token put_policy = Qiniu::Auth::PutPolicy.new('konata') put_policy.return_body = { fname: '$(fname)', hash: '$(etag)', title: '$(x:title)' }.to_json put_policy.return_url = create_posts_url Qiniu::Auth.generate_uptoken(put_policy) end

編輯 config/routes.rb,將 create action 定義為使用 get 方法亦可訪問:

 resources :posts do collection do get 'create', as: :create end end

重新啟動 rails server,訪問 http://localhost:3000/posts/new,現在我們已經可以在發表新 post 的時候上傳圖片至七牛云存儲。

提示:

文件將會上傳到名為 konata 的公開空間(bucket)。
我們沒有在代碼中指定 key,七牛云存儲默認會使用根據文件內容計算的 hash (etag) 值做為 key。這種做法可以非常簡單地避免內容相同的文件存儲多份浪費空間。
由于上傳表單將會直接提交到七牛云存儲服務器,我們的應用程序后端無法獲得 title 等業務對象字段,我們使用七牛云存儲 API 的 自定義變量 和 自定義響應內容 功能,通過七牛云存儲上傳 API 中轉獲得這些字段。
展示用戶上傳的圖片

修改 app/helpers/application_helper.rb,添加 qiniu_image_url 方便生成圖片 URL。為了保持簡單我們直接硬編碼了空間的域名:

def qiniu_image_url(post, format = :raw) url = "http://7xokus.com2.z0.glb.qiniucdn.com/#{post.qiniu_hash}" case format when :square url << '?imageView2/1/w/300/h/300/q/90' when :preview url << '?imageView2/2/w/1000/h/1000/q/90' when :raw url << "?attname=#{post.filename}" else url end end

修改 app/views/posts/index.html.erb 和 app/views/posts/show.html.erb,調用剛才創建的 URL helper 展示圖片:

<tr> <td><%= post.title %></td> <td><%= link_to image_tag(qiniu_image_url(post, :square), size: '300'), post %></td> <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr>
<p> <%= link_to image_tag(qiniu_image_url(@post, :preview)), qiniu_image_url(@post), class: 'image' %></p><%= link_to 'Back', posts_path %>

修改 config/routes.rb,將網站根目錄設置為 posts 列表頁面:


root 'posts#index'
訪問 http://localhost:3000,現在我們可以看到剛才上傳的圖片。

提示:

每個空間(bucket)內的資源都可以通過該空間的默認或自定義域名,加上文件 key 構造的 HTTP URL 進行訪問。
可以在 URL 后增加特定查詢參數,調用七牛云存儲強大的 數據處理(Fop) API,實時生成自定義格式的縮略圖。
可以通過查詢參數 attname 指定 URL 下載時使用的文件名。
簡單的 UI 美化

修改 app/views/posts/index.html.erb,將原有的 table 布局改為 flexbox 布局:

<div class="posts"> <% @posts.each do |post| %> <p> <%= link_to image_tag(qiniu_image_url(post, :square), size: '300'), post, class: 'image' %> <br> <%= post.title %> <br> <%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %> </p> <% end %></div>

修改 app/assets/stylesheets/application.css,加入對應的 CSS:

body { padding: 20px;}a.image:hover { background-color: transparent;}div.posts { display: flex; flex-flow: row wrap; justify-content: space-between;}

訪問 http://localhost:3000,圖片列表看起來像一個正常的相冊了。

添加用戶賬戶功能

我們的應用程序還有兩個明顯的問題:沒有記錄圖片是由誰分享的;任何人都可以刪除 post。這對于一個社交應用來說顯然是不能接受的問題。這對于一個社交應用來說顯然是不可接受的,所以接下來我們將使用 Rails 社區流行的 Devise 組件直接獲得用戶注冊、登錄、驗證子系統,實現圖片發表者信息記錄等功能。

修改 Gemfile,加入對 Devise 的依賴:

 

復制代碼代碼如下:

gem 'devise'

 

執行以下命令安裝 Devise,生成 User model,以及我們所需的 data migration:

 

復制代碼代碼如下:

bundle
rails generate devise:install
rails generate devise user
rails generate migration add_author_to_posts creator:belongs_to
rake db:migrate

 

修改 app/controllers/posts_controller.rb,對查看以外的操作要求登錄,并在發表 post 時記錄發表者身份:

 before_action :authenticate_user!, except: [:index, :show] def create # ... @post = Post.new( title: upload_ret['title'], filename: upload_ret['fname'], qiniu_hash: upload_ret['hash'], creator: current_user ) # ... end

修改 app/models/post.rb,添加與 User model 的從屬關聯:

 

復制代碼代碼如下:

belongs_to :creator, class_name: 'User'

修改 app/views/layouts/application.html.erb,添加登錄狀態信息和注銷鏈接:

 

 <header> <% if user_signed_in? %> <p> Hello <%= current_user.email %> <%= link_to 'Logout', destroy_user_session_path, method: :delete %> </p> <% end %> </header>

修改 app/views/posts/index.html.erb,限制僅 post 發表者可以刪除該 post:

<% if user_signed_in? and post.creator == current_user %> <br> <%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %>

重啟 rails server 后,訪問 http://localhost:3000,現在用戶需要注冊登錄才能發表圖片了。

實現點贊功能

最后,做為一個社交應用,沒有點贊功能怎么能讓點贊狂魔們滿足呢?!我們將添加一個 like scaffold 用來處理點贊和存儲點贊信息。

執行以下命令生成 scaffold,Like model 將做為一個 join model 同時從屬于 Post 和 User:

 

復制代碼代碼如下:

rails generate scaffold like post:belongs_to user:belongs_to
rake db:migrate

 

修改 app/models/post.rb,建立 Post 與 Like model 的“擁有/嵌套”關系:

 

復制代碼代碼如下:

has_many :likes

修改 app/models/like.rb,限制一個點贊狂魔對一個 post 只能點一次贊:

 

 

復制代碼代碼如下:

validates_uniqueness_of :user, scope: :post

修改 config/routes.rb,將 likes 設置為 posts 的嵌套資源:

 

 

復制代碼代碼如下:

resources :posts do
# ...
resources :likes
end

修改 app/views/posts/index.html.erb,添加點贊信息顯示以及 AJAX 點贊鏈接:

 

<%= post.title %> <br> <%= content_tag(:span, "#{post.likes.count} likes", id: "post_#{post.id}_likes") %> <% if user_signed_in? %> <br> <%= link_to 'Like', post_likes_path(post), method: :post, remote: true %> <% if post.creator == current_user %> <%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %> <% end %>

修改 app/controllers/likes_controller.rb,真正將 likes 資源實現為 posts 的嵌套資源,并在點贊時記錄點贊狂魔的身份:

before_action :set_post def create @like = @post.likes.new(user: current_user) respond_to do |format| if @like.save format.js { } else format.js { } end end end private def set_post @post = Post.find(params[:post_id]) end

創建 app/views/likes/create.js.erb,使用 Server-generated JavaScript 更新點贊信息:

 

復制代碼代碼如下:

$("#<%= "post_#{@post.id}_likes" %>").text("<%= "#{@post.likes.count} likes" %>")

重啟 rails server 后,訪問 http://localhost:3000,讓我們愉快地點贊吧~

 

小結

雖然這只是一個簡單的原型,但是因為使用了七牛云存儲作為圖片存儲后端,我們的社交應用產品在一開始的原型階段就擁有了能為大規模用戶提供高速、可靠服務的潛能。

簡單回顧一下我們剛才學習到的內容吧。使用 Rails 的代碼生成功能, 基于 CRUD 結構的 scaffold 實現業務對象維護,以及業務操作非常高效;使用七牛云存儲則可以輕松處理業務系統中的文件存儲,獲得圖片視頻等多媒體文件的云端處理能力,減少,甚至避免了部分研發和運維工作。希望這個視頻可以幫助大家認識這兩個優秀的開發工具,直觀感受到它們的高效強大和簡單易用。

參考資料

Ruby on Rails Guides
七牛開發者中心

示例代碼

https://github.com/rainux/konata-sample

比起直接試用示例代碼,你應該按照教程自己編寫這些代碼,親自編寫代碼有助于加深理解和記憶。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
51久久精品夜色国产麻豆| 另类美女黄大片| 91亚洲国产成人精品性色| 精品视频久久久久久| 亚洲另类激情图| 亚洲欧美日韩久久久久久| 久久久精品日本| 国产精品三级美女白浆呻吟| 日韩av在线免费看| 欧美俄罗斯乱妇| 中文字幕亚洲一区二区三区| 精品国产精品三级精品av网址| 亚洲天堂精品在线| 亚洲一区999| 成人h片在线播放免费网站| 国产美女扒开尿口久久久| 日韩中文字幕免费看| 久久久久久免费精品| 色妞一区二区三区| 91av视频在线| 秋霞午夜一区二区| 日本精品一区二区三区在线播放视频| 久久精品国产一区二区电影| 亚洲已满18点击进入在线看片| xvideos亚洲| 欧美xxxx18国产| 亚洲xxx视频| 日韩a**站在线观看| 亚洲国产精品久久久久| 51色欧美片视频在线观看| 国产精品a久久久久久| 欧美一区二区三区艳史| 久久人人爽国产| www.日韩不卡电影av| 亚洲第一免费播放区| 久久久久亚洲精品国产| 欧美激情精品久久久久久蜜臀| 午夜精品一区二区三区av| 国产一区二区三区18| 97精品国产97久久久久久春色| 九九精品在线观看| 日韩欧美在线看| 欧美小视频在线观看| 97在线免费视频| 51午夜精品视频| 久久久国产精品视频| 欧美视频免费在线观看| 性欧美xxxx视频在线观看| 精品国产91久久久| 亚洲人成在线免费观看| 亚洲免费一在线| 色妞在线综合亚洲欧美| 欧美www视频在线观看| 国产做受69高潮| 岛国av一区二区三区| 国产精品日韩精品| 2019最新中文字幕| 亚洲欧美国产高清va在线播| 色偷偷噜噜噜亚洲男人的天堂| 欧美国产日产韩国视频| 欧美xxxx18性欧美| 欧美精品videossex性护士| 国产精品视频1区| 国产91在线播放九色快色| 日韩精品中文字幕久久臀| 亚洲黄色av网站| 欧洲成人免费视频| 日韩欧美中文第一页| 亚洲全黄一级网站| 国产日韩专区在线| 欧美成人午夜免费视在线看片| 日韩电影中文字幕在线观看| 亚洲国产精品美女| 性金发美女69hd大尺寸| 日韩美女福利视频| 伊人伊成久久人综合网小说| 国产精品亚洲片夜色在线| 一区二区三区视频免费| 91视频九色网站| 亚洲伊人久久大香线蕉av| 欧美精品xxx| 久久精品影视伊人网| 欧美精品做受xxx性少妇| 亚洲欧洲在线免费| 国产精品狠色婷| 国产亚洲精品高潮| 亚洲黄一区二区| 欧美日韩人人澡狠狠躁视频| 精品久久久久久电影| 欧美激情综合亚洲一二区| 亚洲区一区二区| 午夜精品久久久久久久久久久久| 91九色单男在线观看| 97成人精品区在线播放| 欧美日韩在线另类| 性欧美在线看片a免费观看| 久久精品视频中文字幕| 久久99久久99精品中文字幕| 日本电影亚洲天堂| 欧美午夜性色大片在线观看| 日韩亚洲在线观看| 欧美日韩人人澡狠狠躁视频| 久久免费精品日本久久中文字幕| 国产乱人伦真实精品视频| 日韩最新中文字幕电影免费看| 欧美在线视频网站| 性欧美xxxx视频在线观看| 欧美国产日韩一区二区| 亚洲精品999| 日韩成人中文字幕| 亚洲一二在线观看| 久久国产视频网站| 九九综合九九综合| 精品亚洲一区二区三区在线播放| 美女福利视频一区| 日本精品一区二区三区在线播放视频| 精品一区二区亚洲| 亚洲第一福利网站| 日韩小视频网址| 少妇精69xxtheporn| 成人国产精品久久久久久亚洲| 亚洲精品资源在线| 爱福利视频一区| 国语对白做受69| 国产主播喷水一区二区| 国产精品中文久久久久久久| 久久中文久久字幕| 欧美视频在线看| 亚洲欧美在线免费观看| 粉嫩av一区二区三区免费野| 成人性生交xxxxx网站| 亚洲欧美一区二区三区久久| 日韩欧美福利视频| 91tv亚洲精品香蕉国产一区7ujn| 日韩在线视频二区| 久久国产精品网站| 丝袜美腿精品国产二区| 日韩精品在线视频美女| 国产精品免费视频xxxx| www.国产精品一二区| 91tv亚洲精品香蕉国产一区7ujn| 精品国产成人在线| 亚洲最新在线视频| www.久久久久| 国内精品美女av在线播放| 国产成人精品日本亚洲| 日韩激情视频在线播放| 伊人久久久久久久久久久| 国产精品啪视频| 日韩成人高清在线| 午夜精品久久久久久久白皮肤| 超薄丝袜一区二区| 亚洲精品国产美女| 欧美性xxxx| 91精品视频在线| 欧美精品一区二区三区国产精品| 91国产精品视频在线| 久久久91精品国产一区不卡| 久久综合免费视频| 日韩高清欧美高清| 日韩欧美中文第一页| 亚洲自拍偷拍福利| 亚洲免费av网址| 欧美丰满少妇xxxxx做受|