<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 7.1 顯示用戶的信息 ![profile mockup profile name bootstrap](https://box.kancloud.cn/2016-05-11_5732bd102e129.png)圖 7.1:本節實現的用戶資料頁面構思圖 本節要實現的用戶資料頁面是完整頁面的一小部分,只顯示用戶的名字和頭像,構思圖如[圖 7.1](#fig-profile-mockup-profile-name) 所示。[[1](#fn-1)] 最終完成的用戶資料頁面會顯示用戶的頭像、基本信息和微博列表,構思圖如[圖 7.2](#fig-profile-mockup) 所示。[[2](#fn-2)](在圖 7.2 中,我們第一次用到了“lorem ipsum”占位文字,[這些文字背后的故事](http://www.straightdope.com/columns/read/2290/what-does-the-filler-text-lorem-ipsum-mean)很有意思,有空的話你可以了解一下。)這個資料頁面會和整個演示應用一起在[第 12 章](chapter12.html#following-users)完成。 如果你一直堅持使用版本控制,現在像之前一樣,新建一個主題分支: ``` $ git checkout master $ git checkout -b sign-up ``` ![profile mockup bootstrap](https://box.kancloud.cn/2016-05-11_5732bd1049c33.png)圖 7.2:最終實現的用戶資料頁面構思圖 ## 7.1.1 調試信息和 Rails 環境 本節要實現的用戶資料頁面是第一個真正意義上的動態頁面。雖然視圖的代碼不會動態改變,不過每個用戶資料頁面顯示的內容卻是從數據庫中讀取的。添加動態頁面之前,最好做些準備工作,現在我們能做的就是在網站布局中加入一些調試信息,如[代碼清單 7.1](#listing-rails-debug) 所示。這段代碼使用 Rails 內置的 `debug` 方法和 `params` 變量([7.1.2 節](#a-users-resource)會詳細介紹),在各個頁面顯示一些對開發有幫助的信息。 ##### 代碼清單 7.1:在網站布局中添加一些調試信息 app/views/layouts/application.html.erb ``` <!DOCTYPE html> <html> . . . <body> <%= render 'layouts/header' %> <div class="container"> <%= yield %> <%= render 'layouts/footer' %> <%= debug(params) if Rails.env.development? %> </div> </body> </html> ``` 因為我們不想在線上網站中向用戶顯示調試信息,所以上述代碼使用 `if Rails.env.development?` 限制只在開發環境中顯示調試信息。開發環境是 Rails 默認支持的三個環境之一([旁注 7.1](#aside-rails-environments))。[[3](#fn-3)]`Rails.env.development?` 的返回值只在開發環境中才是 `true`,所以下面這行嵌入式 Ruby 代碼 ``` <%= debug(params) if Rails.env.development? %> ``` 不會在生產環境和測試環境中執行。(在測試環境中顯示調試信息雖然沒有壞處,但也沒什么好處,所以最好只在開發環境中顯示。) ##### 旁注 7.1:Rails 環境 Rails 定義了三個環境,分別是測試環境、開發環境和生產環境。Rails 控制臺默認使用的是開發環境: ``` $ rails console Loading development environment >> Rails.env => "development" >> Rails.env.development? => true >> Rails.env.test? => false ``` 如前所示,`Rails` 對象有一個 `env` 屬性,屬性上還可以調用各環境對應的布爾值方法,例如,`Rails.env.test?`,在測試環境中的返回值是 `true`,在其他兩個環境中的返回值則是 `false`。 如果需要在其他環境中使用控制臺(例如,在測試環境中調試),只需把環境名傳給 `console` 命令即可: ``` $ rails console test Loading test environment >> Rails.env => "test" >> Rails.env.test? => true ``` Rails 本地服務器和控制臺一樣,默認使用開發環境,不過也可以在其他環境中運行: ``` $ rails server --environment production ``` 如果要在生產環境中運行應用,先要有一個生產數據庫。在生產環境中執行 `rake db:migrate` 命令可以生成這個數據庫: ``` $ bundle exec rake db:migrate RAILS_ENV=production ``` (我發現在控制臺、服務器和遷移命令中指定環境的方法不一樣,可能會混淆,所以特意演示了這三個命令的用法。) 順便說一下,把應用部署到 Heroku 后,可以使用 `heroku run console` 命令進入控制臺查看使用的環境: ``` $ heroku run console >> Rails.env => "production" >> Rails.env.production? => true ``` Heroku 是用來部署網站的平臺,自然會在生產環境中運行應用。 為了讓調試信息看起來漂亮一些,我們在[第 5 章](chapter5.html#filling-in-the-layout)創建的自定義樣式表文件中加入一些樣式規則,如[代碼清單 7.2](#listing-mixin-and-debug) 所示。 ##### 代碼清單 7.2:添加美化調試信息的樣式,使用了一個 Sass 混入 app/assets/stylesheets/custom.css.scss ``` @import "bootstrap-sprockets"; @import "bootstrap"; /* mixins, variables, etc. */ $gray-medium-light: #eaeaea; @mixin box_sizing { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } . . . /* miscellaneous */ .debug_dump { clear: both; float: left; width: 100%; margin-top: 45px; @include box_sizing; } ``` 這段代碼用到了 Sass 的“混入”(mixin)功能,創建的這個混入名為 `box-sizing`。混入用來打包一系列樣式規則,可多次使用。預處理器會把 ``` .debug_dump { . . . @include box_sizing; } ``` 轉換成 ``` .debug_dump { . . . -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } ``` [7.2.1 節](#using-form-for)會再次用到這個混入。美化后的調試信息如[圖 7.3](#fig-home-page-with-debug) 所示。 [圖 7.3](#fig-home-page-with-debug) 中的調試信息顯示了當前頁面的一些有用信息: ``` --- controller: static_pages action: home ``` 這是 `params` 變量的 YAML [[4](#fn-4)]形式,和哈希類似,顯示當前頁面的控制器名和動作名。[7.1.2 節](#a-users-resource)會介紹其他調試信息的意思。 ![home page with debug 3rd edition](https://box.kancloud.cn/2016-05-11_5732bd106151c.png)圖 7.3:顯示有調試信息的演示應用首頁 ## 7.1.2 用戶資源 為了實現用戶資料頁面,數據庫中要有用戶記錄,這引出了“先有雞還是先有蛋”的問題:網站還沒有注冊頁面,怎么可能有用戶呢?其實這個問題在 [6.3.4 節](chapter6.html#creating-and-authenticating-a-user)已經解決了,那時我們自己動手在 Rails 控制臺中創建了一個用戶,所以數據庫中應該有一個用戶記錄: ``` $ rails console >> User.count => 1 >> User.first => #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2014-08-29 02:58:28", updated_at: "2014-08-29 02:58:28", password_digest: "$2a$10$YmQTuuDNOszvu5yi7auOC.F4G//FGhyQSWCpghqRWQW..."> ``` (如果你的數據庫中現在沒有用戶記錄,回到 [6.3.4 節](chapter6.html#creating-and-authenticating-a-user),在繼續閱讀之前完成那里的操作。)從控制臺的輸出可以看出,這個用戶的 ID 是 `1`,我們現在的目標就是創建一個頁面,顯示這個用戶的信息。我們會遵從 Rails 使用的 REST 架構([旁注 2.2](chapter2.html#aside-rest)),把數據視為資源,可以創建、顯示、更新和刪除。這四個操作分別對應 [HTTP 標準](http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol)中的 `POST`、`GET`、`PATCH` 和 `DELETE` 請求方法([旁注 3.2](chapter3.html#aside-get-etc))。 按照 REST 架構的規則,資源一般由資源名加唯一標識符表示。我們把用戶看做一個資源,若要查看 ID 為 1 的用戶,就要向 /users/1 發送 `GET` 請求。這里沒必要指明用哪個動作,Rails 的 REST 功能解析時,會自動把這個 `GET` 請求交給 `show` 動作處理。 [2.2.1 節](chapter2.html#a-user-tour)介紹過,ID 為 1 的用戶對應的 URL 是 /users/1,不過現在訪問這個 URL 的話,會顯示錯誤信息,如[圖 7.4](#fig-profile-routing-error) 中的服務器日志所示。 ![profile routing error 3rd edition](https://box.kancloud.cn/2016-05-11_5732bd107e1a1.png)圖 7.4:訪問 /users/1 時服務器日志中顯示的錯誤 我們只需在路由文件 `config/routes.rb` 中添加如下的一行代碼就可以正常訪問 /users/1 了: ``` resources :users ``` 修改后的路由文件如[代碼清單 7.3](#listing-users-resource) 所示。 ##### 代碼清單 7.3:在路由文件中添加用戶資源的規則 config/routes.rb ``` Rails.application.routes.draw do root 'static_pages#home' get 'help' => 'static_pages#help' get 'about' => 'static_pages#about' get 'contact' => 'static_pages#contact' get 'signup' => 'users#new' resources :users end ``` 我們的目的只是為了顯示用戶資料頁面,可是 `resources :users` 不僅讓 /users/1 可以訪問,而且還為演示應用中的用戶資源提供了符合 REST 架構的所有動作,[[5](#fn-5)]以及用來獲取相應 URL 的具名路由([5.3.3 節](chapter5.html#using-named-routes))。最終得到的 URL、動作和具名路由的對應關系如[表 7.1](#table-restful-users) 所示(和[表 2.2](chapter2.html#table-demo-restful-users) 對比一下)。接下來的三章會介紹[表 7.1](#table-restful-users) 中的所有動作,并不斷完善,把用戶打造成完全符合 REST 架構的資源。 表 7.1:[代碼清單 7.3](#listing-users-resource) 中添加的用戶資源規則實現的 REST 架構路由 | HTTP 請求 | URL | 動作 | 具名路由 | 作用 | | --- | --- | --- | --- | --- | | `GET` | /users | `index` | `users_path` | 顯示所有用戶的頁面 | | `GET` | /users/1 | `show` | `user_path(user)` | 顯示單個用戶的頁面 | | `GET` | /users/new | `new` | `new_user_path` | 創建(注冊)新用戶的頁面 | | `POST` | /users | `create` | `users_path` | 創建新用戶 | | `GET` | /users/1/edit | `edit` | `edit_user_path(user)` | 編輯 ID 為 1 的用戶頁面 | | `PATCH` | /users/1 | `update` | `user_path(user)` | 更新用戶信息 | | `DELETE` | /users/1 | `destroy` | `user_path(user)` | 刪除用戶 | 添加[代碼清單 7.3](#listing-users-resource) 中的代碼之后,路由就生效了,但是頁面還不存在([圖 7.5](#fig-user-show-unknown-action))。下面我們在頁面中添加一些簡單的內容,[7.1.4 節](#a-gravatar-image-and-a-sidebar)還會添加更多內容。 ![user show unknown action 3rd edition](https://box.kancloud.cn/2016-05-11_5732bd10a1b48.png)圖 7.5:/users/1 的路由生效了,但頁面不存在 用戶資料頁面的視圖保存在標準的位置,即 `app/views/users/show.html.erb`。這個視圖和自動生成的 `new.html.erb`([代碼清單 5.28](chapter5.html#listing-generate-users-controller))不同,現在不存在,要手動創建,然后寫入[代碼清單 7.4](#listing-stub-user-view) 中的代碼。 ##### 代碼清單 7.4:用戶資料頁面的臨時視圖 app/views/users/show.html.erb ``` <%= @user.name %>, <%= @user.email %> ``` 在這段代碼中,我們假設存在一個 `@user` 變量,使用 ERb 代碼顯示這個用戶的名字和電子郵件地址。這和最終實現的視圖有點不一樣,屆時不會公開顯示用戶的電子郵件地址。 我們要在用戶控制器的 `show` 動作中定義 `@user` 變量,用戶資料頁面才能正常渲染。你可能猜到了,我們要在用戶模型上調用 `find` 方法([6.1.4 節](chapter6.html#finding-user-objects)),從數據庫中取出用戶記錄,如[代碼清單 7.5](#listing-user-show-action) 所示。 ##### 代碼清單 7.5:含有 `show` 動作的用戶控制器 app/controllers/users_controller.rb ``` class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new end end ``` 在這段代碼中,我們使用 `params` 獲取用戶的 ID。當我們向用戶控制器發送請求時,`params[:id]` 會返回用戶的 ID,即 1,所以這就和 [6.1.4 節](chapter6.html#finding-user-objects)中直接調用 `User.find(1)` 的效果一樣。(嚴格來說,`params[:id]` 返回的是字符串 `"1"`,`find` 方法會自動將其轉換成整數。) 定義視圖和動作之后,/users/1 就可以正常訪問了,如[圖 7.6](#fig-user-show-rails) 所示。(如果添加 bcrypt 之后沒重啟過 Rails 服務器,現在或許要重啟。)留意一下調試信息,證實了 `params[:id]` 的值和前面分析的一樣: ``` --- action: show controller: users id: '1' ``` 所以,[代碼清單 7.5](#listing-user-show-action) 中的 `User.find(params[:id])` 才會取回 ID 為 1 的用戶。 ![user show 3rd edition](https://box.kancloud.cn/2016-05-11_5732bd10be549.png)圖 7.6:添加 `show` 動作后的用戶資料頁面 ## 7.1.3 調試器 在 [7.1.2 節](#a-users-resource)看到,調試信息能幫助我們理解應用的運作方式。從 Rails 4.2 開始,可以使用 `byebug` gem([代碼清單 3.2](chapter3.html#listing-gemfile-sample-app))更直接地獲取調試信息。我們把 `debugger` 加到應用中,看一下這個 gem 的作用,如[代碼清單 7.6](#listing-debugger) 所示。 ##### 代碼清單 7.6:在用戶控制器中使用調試器 app/controllers/users_controller.rb ``` class UsersController < ApplicationController def show @user = User.find(params[:id]) debugger end def new end end ``` 現在訪問 /users/1 時,會在 Rails 服務器的輸出中顯示 `byebug` 提示符: ``` (byebug) ``` 我們可以把它當成 Rails 控制臺,在其中執行代碼,看一下應用的狀態: ``` (byebug) @user.name "Example User" (byebug) @user.email "example@railstutorial.org" (byebug) params[:id] "1" ``` 若想退出 `byebug`,繼續執行應用,可以按 Ctrl-D 鍵。然后把 `show` 動作中的 `debugger` 刪除,如[代碼清單 7.7](#listing-debugger-removed) 所示。 ##### 代碼清單 7.7:刪除調試器后的用戶控制器 app/controllers/users_controller.rb ``` class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new end end ``` 只要你覺得 Rails 應用中哪部分有問題,就可以在可能導致問題的代碼附近加上 `debugger`。`byebug` 很強大,可以查看系統的狀態,查找應用錯誤,以及交互式調試應用。 ## 7.1.4 Gravatar 頭像和側邊欄 前面創建了一個略顯簡陋的用戶資料頁面,這一節要再添加一些內容:用戶頭像和側邊欄。首先,我們要在用戶資料頁面中添加一個“全球通用識別”的頭像,或者叫 [Gravatar](http://gravatar.com/)。[[6](#fn-6)]這是一個免費服務,讓用戶上傳圖片,將其關聯到自己的電子郵件地址上。使用 Gravatar 可以簡化在網站中添加用戶頭像的過程,開發者不必分心去處理圖片上傳、剪裁和存儲,只要使用用戶的電子郵件地址構成頭像的 URL 地址,用戶的頭像就會顯示出來。([11.4 節](chapter11.html#micropost-images)會介紹如何處理圖片上傳。) 我們的計劃是,定義一個名為 `gravatar_for` 的輔助方法,返回指定用戶的 Gravatar 頭像,如[代碼清單 7.8](#listing-user-show-view-with-gravatar) 所示。 ##### 代碼清單 7.8:顯示用戶名字和 Gravatar 頭像的用戶資料頁面視圖 app/views/users/show.html.erb ``` <% provide(:title, @user.name) %> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> ``` 默認情況下,所有輔助方法文件中定義的方法都自動在任意視圖中可用,不過為了便于管理,我們會把 `gravatar_for` 方法放在用戶控制器對應的輔助方法文件中。根據 [Gravatar 的文檔](http://en.gravatar.com/site/implement/hash/),頭像的 URL 地址中要使用用戶電子郵件地址的 [MD5 哈希值](http://en.wikipedia.org/wiki/MD5)。在 Ruby 中,MD5 哈希算法由 `Digest` 庫中的 `hexdigest` 方法實現: ``` >> email = "MHARTL@example.COM". >> Digest::MD5::hexdigest(email.downcase) => "1fda4469bcbec3badf5418269ffc5968" ``` 電子郵件地址不區分大小寫,但是 MD5 哈希算法區分,所以我們要先調用 `downcase` 方法把電子郵件地址轉換成小寫形式,然后再傳給 `hexdigest` 方法。(在[代碼清單 6.31](chapter6.html#listing-email-downcase) 中的回調里我們已經把電子郵件地址轉換成小寫形式了,但這里最好也轉換,以防電子郵件地址來自其他地方。)我們定義的 `gravatar_for` 輔助方法如[代碼清單 7.9](#listing-gravatar-for-helper) 所示。 ##### 代碼清單 7.9:定義 `gravatar_for` 輔助方法 app/helpers/users_helper.rb ``` module UsersHelper # 返回指定用戶的 Gravatar def gravatar_for(user) gravatar_id = Digest::MD5::hexdigest(user.email.downcase) gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}" image_tag(gravatar_url, alt: user.name, class: "gravatar") end end ``` `gravatar_for` 方法的返回值是一個 `img` 元素,用于顯示 Gravatar 頭像。`img` 標簽的 CSS 類為 `gravatar`,`alt` 屬性的值是用戶的名字(對視覺障礙人士使用的屏幕閱讀器特別有用)。 用戶資料頁面如[圖 7.7](#fig-profile-with-gravatar) 所示,頁面中顯示的頭像是 Gravatar 的默認圖片,因為 `user@example.com` 不是真的電子郵件地址(example.com 這個域名是專門用來舉例的)。 ![profile with gravatar 3rd edition](https://box.kancloud.cn/2016-05-11_5732bd10d4433.png)圖 7.7:顯示 Gravatar 默認頭像的用戶資料頁面![profile custom gravatar 3rd edition](https://box.kancloud.cn/2016-05-11_5732bd10ecb5d.png)圖 7.8:顯示真實頭像的用戶資料頁面 我們調用 `update_attributes` 方法([6.1.5 節](chapter6.html#updating-user-objects))更新一下數據庫中的用戶記錄,然后就可以顯示用戶真正的頭像了: ``` $ rails console >> user = User.first >> user.update_attributes(name: "Example User", ?> email: "example@railstutorial.org", ?> password: "foobar", ?> password_confirmation: "foobar") => true ``` 我們把用戶的電子郵件地址改成 `example@railstutorial.org`。我已經把這個地址的頭像設為了本書網站的 LOGO,修改后的結果如[圖 7.8](#fig-profile-custom-gravatar) 所示。 我們還要添加一個側邊欄,才能完成[圖 7.1](#fig-profile-mockup-profile-name) 中的構思圖。我們要使用 `aside` 標簽定義側邊欄。`aside` 中的內容一般是對主體內容的補充(例如側邊欄),不過也可以自成一體。我們要把 `aside` 標簽的類設為 `row col-md-4`,這兩個類都是 Bootstrap 提供的。在用戶資料頁面中添加側邊欄所需的代碼如[代碼清單 7.10](#listing-user-show-with-sidebar) 所示。 ##### 代碼清單 7.10:在 `show` 動作的視圖中添加側邊欄 app/views/users/show.html.erb ``` <% provide(:title, @user.name) %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> </section> </aside> </div> ``` 添加 HTML 結構和 CSS 類之后,我們再用 SCSS 為資料頁面定義一些樣式,如[代碼清單 7.11](#listing-sidebar-css) 所示。[[7](#fn-7)](注意:因為 Asset Pipeline 使用 Sass 預處理器,所以樣式中才可以使用嵌套。)實現的效果如[圖 7.9](#fig-user-show-sidebar-css) 所示。 ##### 代碼清單 7.11:用戶資料頁面的樣式,包括側邊欄的樣式 app/assets/stylesheets/custom.css.scss ``` . . . /* sidebar */ aside { section.user_info { margin-top: 20px; } section { padding: 10px 0; margin-top: 20px; &:first-child { border: 0; padding-top: 0; } span { display: block; margin-bottom: 3px; line-height: 1; } h1 { font-size: 1.4em; text-align: left; letter-spacing: -1px; margin-bottom: 3px; margin-top: 0px; } } } .gravatar { float: left; margin-right: 10px; } .gravatar_edit { margin-top: 15px; } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看