Railsチュートリアル:7章
7章。ユーザー編続き。
まずはいつも通り、ブランチ作成。
git checkout -b sign-up
リスト 7.1: サイトのレイアウトにデバッグ情報を追加する
app/views/layouts/application.html.erb
<%= debug(params) if Rails.env.development? %>
追加。
リスト 7.2: デバッグ表示を整形するための追加と、Sassのミックスイン.
app/assets/stylesheets/custom.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;
}
追加。
dbに6章で登録したユーザーがきちんといるのかを検証。
ec2-user:~/environment/sample_app (sign-up) $ rails console
Running via Spring preloader in process 4656
Loading development environment (Rails 5.1.6)
>> User.count
(0.1ms) SELECT COUNT(*) FROM "users"
=> 1
>> User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "[email protected]", created_at: "2020-05-05 05:02:56", updated_at: "2020-05-05 05:02:56", password_digest: "$2a$10$zjzfkvsimhFwLB0RuXRQxOIOZSQTyUUyPYabuX7sU37...">
リスト 7.3: Usersリソースをroutesファイルに追加する
config/routes.rb
ユーザーそれぞれのページのルーティング設定。
resources :users
追加。
リスト 7.4: ユーザー情報を表示するための仮のビュー
app/views/users/show.html.erb
手動でビューを作成
<%= @user.name %>, <%= @user.email %>
インスタンス変数があることを前提にしているらしい。
リスト 7.5: Usersコントローラのshowアクション
app/controllers/users_controller.rb
def show
@user = User.find(params[:id])
end
追加。
伝家の宝刀params[:id]
説明は、、、
ユーザーのid読み出しにはparamsを使いました。Usersコントローラにリクエストが正常に送信されると、params[:id]の部分はユーザーidの1に置き換わります。つまり、この箇所は6.1.4で学んだfindメソッドの User.find(1)と同じになります。(技術的な補足: params[:id]は文字列型の "1" ですが、findメソッドでは自動的に整数型に変換されます)。
安定のさらっと。
実際に/users/1ページにアクセス。
すると説明が。
デバッグ情報からparams[:id]の値を確認できることを確認してください (図 7.6)。
action: show
controller: users
id: '1'
このid: '1'は /users/:id から取得した値です。この値を使って
User.find(params[:id])
上のコードでid=1のユーザーを検索できる、といった仕組みになっているのです
いや、まずデバックってなんなのかしらんし。
リスト 7.6: debuggerをUsersコントローラに差し込む
app/controllers/users_controller.rb
debugger
追加。
/users/1 にアクセス
504 Gateway Time-outとでる。
ターミナルをみると
[1, 10] in /home/ec2-user/environment/sample_app/app/controllers/users_controller.rb
1: class UsersController < ApplicationController
2:
3: def show
4: @user = User.find(params[:id])
5: debugger
=> 6: end
7:
8: def new
9: end
10: end
(byebug)
どうやらページはみれないが、続きはできそうである
ビビッて調べたら↓のサイトが
https://rakuda3desu.net/rakudas-rails-tutoria7-1/
(byebug) @user.name
"Michael Hartl"
(byebug) @user.email
"[email protected]"
(byebug) params[:id]
"1"
(byebug) Rendering users/show.html.erb within layouts/application
Rendered users/show.html.erb within layouts/application (0.7ms)
Rendered layouts/_shim.html.erb (0.3ms)
Rendered layouts/_header.html.erb (0.9ms)
Rendered layouts/_footer.html.erb (0.6ms)
Completed 200 OK in 291161ms (Views: 293.1ms | ActiveRecord: 0.7ms)
ターミナル上で作業だけしました。
リスト 7.7: debuggerをUsersコントローラーから取り外す
app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
end
end
デバッガー削除
今後Railsアプリケーションの中でよく分からない挙動があったら、上のようにdebuggerを差し込んで調べてみましょう。トラブルが起こっていそうなコードの近くに差し込むのがコツです。byebug gemを使ってシステムの状態を調査することは、アプリケーション内のエラーを追跡したりデバッグするときに非常に強力なツールになります。
とのこと。イミフ。
もう一度、users/1にアクセスしてみた。
元通りアクセスできた。よかった。
リスト 7.8: ユーザー表示ビューに名前とGravatarを表示する
app/views/users/show.html.erb
<% provide(:title, @user.name) %>
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
書き換え。
リスト 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
追加。
dbの登録情報を変える指示。
ec2-user:~/environment/sample_app (sign-up) $ rails console
Running via Spring preloader in process 5981
Loading development environment (Rails 5.1.6)
>> user = User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "[email protected]", created_at: "2020-05-05 05:02:56", updated_at: "2020-05-05 05:02:56", password_digest: "$2a$10$zjzfkvsimhFwLB0RuXRQxOIOZSQTyUUyPYabuX7sU37...">
>> user.update_attributes(name: "Example User",
?> ?> email: "[email protected]",
?> ?> password: "foobar",
?> ?> password_confirmation: "foobar")
Traceback (most recent call last):
SyntaxError ((irb):3: syntax error, unexpected tIDENTIFIER, expecting =>)
?> email: "[email protected]",
^~~~~
>> user.update_attributes(name: "Example User",
?> ?> email: "[email protected]",
?> ?> password: "foobar",
?> ?> password_confirmation: "foobar")
Traceback (most recent call last):
SyntaxError ((irb):7: syntax error, unexpected tIDENTIFIER, expecting =>)
?> email: "[email protected]",
^~~~~
(irb):7: syntax error, unexpected ',', expecting end
...l: "[email protected]",
... ^
(irb):8: syntax error, unexpected ',', expecting end
... password: "foobar",
... ^
(irb):9: syntax error, unexpected ')', expecting end
...assword_confirmation: "foobar")
... ^
エラー祭り。
いろいろ試すと、
コンソールに打ち込む
user.update_attributes(name: "Example User",
?> email: "[email protected]",
?> password: "foobar",
?> password_confirmation: "foobar")
この2~4行目を一気にコピーして打ち込むとダメで一行ずつコピーしてやるといけた。
>> user.update_attributes(name: "Example User",
?> email: "[email protected]",
?> password: "foobar",
?> password_confirmation: "foobar")
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ? [["email", "[email protected]"], ["id", 1], ["LIMIT", 1]]
SQL (3.9ms) UPDATE "users" SET "name" = ?, "email" = ?, "updated_at" = ?, "password_digest" = ? WHERE "users"."id" = ? [["name", "Example User"], ["email", "[email protected]"], ["updated_at", "2020-05-05 08:06:29.274815"], ["password_digest", "$2a$10$dlKmj98ZLEtoQwRbrtM.QOBPvndZXRMfo889DsWvmGHOb8bj/J6vO"], ["id", 1]]
(6.2ms) commit transaction
=> true
リスト 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>
変更
リスト 7.11: SCSSを使ってサイドバーなどのユーザー表示ページにスタイルを与える
app/assets/stylesheets/custom.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;
}
追加。
リスト 7.14: newアクションに@user変数を追加する
app/controllers/users_controller.rb
def new
@user = User.new
end
追加
リスト 7.15: 新規ユーザーのためのユーザー登録フォーム
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_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-primary" %>
<% end %>
</div>
</div>
リスト 7.16: ユーザー登録フォームのCSS
app/assets/stylesheets/custom.scss
※さきこっちらしい
/* forms */
input, textarea, select, .uneditable-input {
border: 1px solid #bbb;
width: 100%;
margin-bottom: 15px;
@include box_sizing;
}
input {
height: auto !important;
}
リスト 7.17: 図 7.12のフォームのHTMLソース
<form accept-charset="UTF-8" action="/users" class="new_user"
id="new_user" method="post">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden"
value="NNb6+J/j46LcrgYUC60wQ2titMuJQ5lLqyAbnbAUkdo=" />
<label for="user_name">Name</label>
<input id="user_name" name="user[name]" type="text" />
<label for="user_email">Email</label>
<input id="user_email" name="user[email]" type="email" />
<label for="user_password">Password</label>
<input id="user_password" name="user[password]"
type="password" />
<label for="user_password_confirmation">Confirmation</label>
<input id="user_password_confirmation"
name="user[password_confirmation]" type="password" />
<input class="btn btn-primary" name="commit" type="submit"
value="Create my account" />
</form>
確認しました。
リスト 7.18: ユーザー登録の失敗に対応できるcreateアクション
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(params[:user]) # 実装は終わっていないことに注意!
if @user.save
# 保存の成功をここで扱う。
else
render 'new'
end
end
end
書き換え
リスト 7.19: createアクションでStrong Parametersを使う
app/controllers/users_controller.rb
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
書き換え。
ここは完全にプロゲートとは違います。
エラーメッセージに関して
>> user = User.new(name: "Foo Bar", email: "foo@invalid",
?> password: "dude", password_confirmation: "dude")
=> #<User id: nil, name: "Foo Bar", email: "foo@invalid", created_at: nil, updated_at: nil, password_digest: "$2a$10$WvMnxBE8Pzi8VitiprtRzugUhSsJMWT0oP9DFA57R1N...">
>> user.save
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ? [["email", "foo@invalid"], ["LIMIT", 1]]
(0.1ms) rollback transaction
=> false
>> user.errors.full_messages
=> ["Email is invalid", "Password is too short (minimum is 6 characters)"]
リスト 7.20: ユーザー登録失敗時にエラーメッセージが表示されるようにする
app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
sharedがでてきたのでまたそれをつくる。
もうこの辺は感覚でしかわからん。
mkdir app/views/shared
リスト 7.21: フォーム送信時にエラーメッセージを表示するためのパーシャル
app/views/shared/_error_messages.html.erb
<% if @user.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(@user.errors.count, "error") %>.
</div>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
演習があるけどうまくいきません
ec2-user:~/environment/sample_app (sign-up) $ rails console
Running via Spring preloader in process 7727
Loading development environment (Rails 5.1.6)
>>
>> user.errors.count
Traceback (most recent call last):
1: from (irb):2
NameError (undefined local variable or method `user' for main:Object)
Did you mean? super
>>
ec2-user:~/environment/sample_app (sign-up) $ rails console
Running via Spring preloader in process 7751
Loading development environment (Rails 5.1.6)
>> user.errors.count
Traceback (most recent call last):
1: from (irb):1
NameError (undefined local variable or method `user' for main:Object)
Did you mean? super
>> user.errors.empty?
Traceback (most recent call last):
2: from (irb):2
1: from (irb):2:in `rescue in irb_binding'
NameError (undefined local variable or method `user' for main:Object)
>> user.errors.any?
Traceback (most recent call last):
2: from (irb):3
1: from (irb):3:in `rescue in irb_binding'
NameError (undefined local variable or method `user' for main:Object)
もうこのままいく。
ここでなぞの演習
>> helper.pluralize(1, "error")
=> "1 error"
>> helper.pluralize(5, "error")
=> "5 errors"
>> helper.pluralize(2, "woman")
=> "2 women"
>> helper.pluralize(3, "erratum")
=> "3 errata"
複数形になるらしい。
リスト 7.22: エラーメッセージにスタイルを与えるためのCSS
app/assets/stylesheets/custom.scss
#error_explanation {
color: red;
ul {
color: red;
margin: 0 0 30px 0;
}
}
.field_with_errors {
@extend .has-error;
.form-control {
color: $state-danger-text;
}
}
追加
ページアクセスして、同じ内容いれてみた。
The form contains 4 errors.
Email is invalid
Password can't be blank
Password can't be blank
Password is too short (minimum is 6 characters)
エラーがひとつおおい&重複
なぞだけど進む。
Author And Source
この問題について(Railsチュートリアル:7章), 我々は、より多くの情報をここで見つけました https://qiita.com/fumi1011/items/157f2e1e199f1c0d099b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .