チュートリアルをやってみる。ユーザ登録画面編
これは以下のチュートリアルをやってみた際のログである。
ユーザ表示ページに表示するもの
- ユーザのプロファイル写真
- ユーザデータ
- マイクロポスト一覧
デバッグ表示
app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> ... <body> <%= render 'layouts/header' %> <div class="container"> <%= yield %> <%= render 'layouts/footer' %> <%= debug(params) if Rails.env.development? %> </div> </body> </html>
Rails.env.development?がtrueならdebug(params)が表示される。
つまり開発環境でしか表示されない。
app/assets/stylesheets/custom.css.scss
@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; }
ルーティング
config/routes.rb
SampleApp::Application.routes.draw do resources :users root 'static_pages#home' match '/signup', to: 'users#new', via: 'get' match '/help', to: 'static_pages#help', via: 'get' match '/about', to: 'static_pages#about', via: 'get' match '/contact', to: 'static_pages#contact', via: 'get' ....
resources :usersとすることで以下のRESTfulなアクションが利用できるようになる。
リクエスト | URL | アクション | 名前付きルート |
GET | /users | index | user_path |
GET | /users/1 | show | user_path(1) |
GET | /users/new | new | new_user_path |
POST | /users | create | users_path |
GET | /users/1/edit | edut | edit_user_path(user) |
PATCH | /users/1 | update | user_path(user) |
DELETE | /user/1 | destroy | user_path(user) |
ユーザ用のビューをつくる。
app/views/users/show.html.erb
<%= @user.name %>, <%= @user.email %>
コントローラ
app/controllers/users_controller.rb
class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new end end
プロフィール写真をつける
Gtavatar
gravatar_for関数はusers_helperで定義。
app/views/users/show.html.erb
<% provide(:title, @user.name) %> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1>
app/helpers/users_helper.rb
# 与えられたユーザーのGravatar (http://gravatar.com/) を返す。 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
確認
user = User.create(name:"p",email:"op@poi.mail",password:"poipoi", password_confirmation:"poipoi") user.save
rails server
サイドバー作成
app/views/users/show.html.erb
<% provide(:title, @user.name) %> <div class="row"> <aside class="span4"> <section> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> </section> </aside> </div>
app/assets/stylesheets/custom.css.scss
/* sidebar */ aside { section { padding: 10px 0; border-top: 1px solid $grayLighter; &: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; }
ユーザ登録フォーム
タイトルがあり、
- name
- password
- condirmation
の入力項目があり、
その下にcreateボタンがある。
ユーザデータのリセット
一度リセットしておく
bundle exec rake db:reset bundle exec rake db:test:prepare
User.countが0であることをrailsコンソールで確認。
フォームのセット form_for
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="span6 offset3"> <%= form_for(@user) do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :email %> <%= f.text_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation %> <%= f.submit "Create my account", class: "btn btn-large btn-primary" %> <% end %> </div> </div>
form_forはフォームを作る。ここから<%end>までがform_forであり、
f.label,f.textなどを使って設定していく。
app/controllers/users_controller.rb
class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new @user = User.new end end
app/assets/stylesheets/custom.css.scss
/* forms */ input, textarea, select, .uneditable-input { border: 1px solid #bbb; width: 100%; padding: 10px; margin-bottom: 15px; @include box_sizing; } input { height: auto !important; }
ローカルサーバで確認
rails server
エラー表示用のモックアップ
前述のフォームの登録は
<form action="/users" class="new_user" id="new_user" method="post">
となっておいるので"/users"にPOSTリクエストが送られるが、これは前述の表のように、
createアクションと結びつけられている。
よって、このcreateアクションでユーザの登録と、その失敗を記述する。
app/controllers/users_controller.rb
class UsersController < ApplicationController .... def create @user = User.new(params[:user]) # 実装は終わっていないことに注意! if @user.save # 保存の成功をここで扱う。 else render 'new' end end end
これだとparams[:user]の中身を変更されて渡される危険性があるため、以下の方法に従う。
class UsersController < ApplicationController ...... def create @user = User.new(user_params) if @user.save # 保存の成功をここで扱う。 else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end
params.require(:user)はユーザ属性を必須とし、permitで許可する属性をしていている。
エラー表示用のタグを埋め込む
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="span6 offset3"> <%= form_for(@user) do |f| %> <%= render 'shared/error_messages' %> .... <% end %> </div> </div>
renderを使って、パーシャル埋め込みをしている。よって、中身は_error_messages.html.erbに書く。
app/views/shared/error_messages.html.erb
<% if @user.errors.any? %> <div id="error_explanation"> <div class="alert alert-error"> The form contains <%= pluralize(@user.errors.count, "error") %>. </div> <ul> <% @user.errors.full_messages.each do |msg| %> <li>* <%= msg %></li> <% end %> </ul> </div> <% end %>
pluralizeはテキストヘルパー
pluralize(1, "error") <==> "1 error"
pluralize(2, "error") <==> "2 errors"
cssも調整
app/assets/stylesheets/custom.css.scss
#error_explanation { color: #f00; ul { list-style: none; margin: 0 0 18px 0; } } .field_with_errors { @extend .control-group; @extend .error; }
@extendはSassの関数、Bootstrapの.control-groupと.errorを使用している。
.field_with_errorsは、railsがエラーが出たフォーム欄に与えるクラス。
ここまででローカルサーバで確認
rails server
データベース保存
- 登録するとリダイレクトしてユーザのページへいく。
app/controllers/users_controller.rb
class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new @user = User.new end def create @user = User.new(user_params) if @user.save redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end
redirect_to @userの一文でUser表示ページへいく。
ウェルカムメッセージを入れる。
app/views/layouts/application.html.erb
<!DOCTYPE html> <html> ... <body> <%= render 'layouts/header' %> <div class="container"> <% flash.each do |key, value| %> <div class="alert alert-<%= key %>"><%= value %></div> <% end %> <%= yield %> <%= render 'layouts/footer' %> <%= debug(params) if Rails.env.development? %> </div> .... </body> </html>
<% flash.each do |key, value| %>
が入っている。flash[:success] = "Welcome to the Sample App!"が入っていれば、
これは
<div class="alert alert-success">Welcome to the Sample App!</div>
と表示される。
その代入をcontroller側に入れる。
app/controllers/users_controller.rb
class UsersController < ApplicationController ..... def create @user = User.new(user_params) if @user.save flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end
ここでローカルサーバで確認してみる。
rails server
本番環境にSSL導入
config/environments/production.rb
SampleApp::Application.configure do .... # Force all access to the app over SSL, use Strict-Transport-Security, # and use secure cookies. config.force_ssl = true end
herokuにもpush
本番データベースでマイグレーション
heroku run rake db:migrate
heroku open