回答編集履歴

1

補足を追加

2021/02/24 12:31

投稿

shinoharat2
shinoharat2

スコア73

test CHANGED
@@ -46,7 +46,77 @@
46
46
 
47
47
  いえ、そういうわけではないです。
48
48
 
49
+
50
+
51
+ 例えば、以下のようなデータを新規作成したとします。
52
+
53
+
54
+
55
+ ```rb
56
+
57
+ User.create!(name: "太郎", email: "aaa@bbb.com", password: "xyz123")
58
+
59
+ ```
60
+
61
+
62
+
63
+ そして、そのデータを find メソッドで取得します。
64
+
65
+ すると、name や email は保存したときの値が取得できますが、 password は nil になっています。
66
+
67
+
68
+
69
+ ```rb
70
+
71
+ # さっき作成したデータを取得
72
+
73
+ user = User.find(さっきのid)
74
+
75
+
76
+
77
+ # 普通は保存したときの値が取得できる。
78
+
49
- ちょっと説明が難しいので、後日時間が取れたら詳しく書かせてください。
79
+ user.name #=> "太郎"
80
+
81
+ user.email #=> "aaa@bbb.com"
82
+
83
+
84
+
85
+ # ただし、password は nil になる
86
+
87
+ user.password #=> nil
88
+
89
+ ```
90
+
91
+
92
+
93
+ なぜなら、DBに保存されているのは、「password」ではなく「password_digest」だからです。
94
+
95
+ 確認してみると、password_digestカラムにハッシュ化されたパスワードが格納されているのがわかります。
96
+
97
+
98
+
99
+ ```rb
100
+
101
+ user.password_digest
102
+
103
+ => "$2a$12$Bc3udhjk8zNWMORNBIK6feRYvF4Ded6WD3.OQVYJ0LJxZ5sJB.b2K"
104
+
105
+ ```
106
+
107
+
108
+
109
+ 「password」は「password_digest」を作るための一時的な入れ物で、DBとは直接つながっていません。
110
+
111
+ なので、DBからロードしたデータの中には「password」が含まれない(nilになる)という形です。
112
+
113
+
114
+
115
+ 「password が nil だからエラーになっている」という認識は正しいですが、
116
+
117
+ 「フォームから nil が送られてきたので password が nil で上書きされた」というわけではありません。
118
+
119
+
50
120
 
51
121
 
52
122
 
@@ -56,4 +126,86 @@
56
126
 
57
127
  今後パスワード更新画面を作る場合、その画面ではパスワードの必須バリデーションを行う必要が出てきます。
58
128
 
129
+ このように、ある特定のタイミングでのみバリデーションを実行させたい場合、 `:on` オプションが利用できます。
130
+
131
+
132
+
133
+ 例えば、以下のように、バリデーションに `on: :change_password` を付与したとします。
134
+
135
+
136
+
137
+ ```rb
138
+
139
+ class User < ApplicationRecord
140
+
141
+ has_secure_password
142
+
143
+
144
+
145
+ validates :password, presence: true, on: :change_password
146
+
147
+ end
148
+
149
+ ```
150
+
151
+
152
+
153
+ このバリデーションは、以下のように、saveメソッドのコンテキストにchange_passwordを指定した場合のみ有効になります。
154
+
155
+
156
+
157
+ ```rb
158
+
159
+ @user.save(context: :change_password)
160
+
161
+ ```
162
+
163
+
164
+
59
- このやり方については、た後日解説させてください
165
+ れを使えば、「特定画面でのみ有効なバリデーション」を作成でき
166
+
167
+
168
+
169
+ ```rb
170
+
171
+ # 実装例
172
+
173
+ class UserController < ApplicationController
174
+
175
+
176
+
177
+ def パスワード更新画面
178
+
179
+ @user = User.find(params[:id])
180
+
181
+
182
+
183
+ @user.attributes = change_password_attributes
184
+
185
+
186
+
187
+ if @user.save(context: :change_password)
188
+
189
+ ・・・
190
+
191
+ end
192
+
193
+ end
194
+
195
+
196
+
197
+ private
198
+
199
+
200
+
201
+ def change_password_attributes
202
+
203
+ params.require(:user).permit(:password)
204
+
205
+ end
206
+
207
+
208
+
209
+ end
210
+
211
+ ```