回答編集履歴

2

解説を追加

2021/03/04 04:08

投稿

shinoharat
shinoharat

スコア1674

test CHANGED
@@ -1,3 +1,7 @@
1
+ ## 修正方法
2
+
3
+
4
+
1
5
  パスワードの検証が常にONになっているのが原因です。
2
6
 
3
7
  User クラスに以下の修正を加えてください。
@@ -21,3 +25,105 @@
21
25
 
22
26
 
23
27
  上記の修正により、「パスワードが nil の場合はバリデーションをスキップする」という動作になります。
28
+
29
+
30
+
31
+
32
+
33
+ ## 解説
34
+
35
+
36
+
37
+ > 疑問なのですがnicknameなどにもpresence: trueをかけているのになぜpasswordのみにバリデーションをスキップするオプションヲッ加えるのでしょうか??
38
+
39
+
40
+
41
+ 良い質問ですね。password カラムの動作について解説します。
42
+
43
+
44
+
45
+ 例えば、以下のようなデータを新規作成したとします。
46
+
47
+
48
+
49
+ ```
50
+
51
+ User.create!(nickname: "もっち", email: "aaa@bbb.com", password: "xyz123", ...)
52
+
53
+ ```
54
+
55
+
56
+
57
+ そして、そのデータを find メソッドで取得します。
58
+
59
+ すると、nickname や email は保存したときの値が取得できるのですが、 password は nil になっています。
60
+
61
+
62
+
63
+ ```
64
+
65
+ # さっき作成したデータを取得
66
+
67
+ user = User.find(さっきのid)
68
+
69
+
70
+
71
+ # 普通は保存したときの値が取得できる。
72
+
73
+ user.nickname #=> "もっち"
74
+
75
+ user.email #=> "aaa@bbb.com"
76
+
77
+
78
+
79
+ # ただし、password は nil になる
80
+
81
+ user.password #=> nil
82
+
83
+ ```
84
+
85
+
86
+
87
+ なぜなら、DBに保存されているのは、「password」ではなく「encrypted_password」だからです。
88
+
89
+ 確認してみると、encrypted_passwordカラムには、ハッシュ化されたパスワードが格納されているのがわかります。
90
+
91
+
92
+
93
+ ```
94
+
95
+ user.encrypted_password
96
+
97
+ => "...ハッシュ化されたパスワード..."
98
+
99
+ ```
100
+
101
+
102
+
103
+ 「password」は「encrypted_password」を作るための一時的な入れ物で、DBと連動しているわけではありません。
104
+
105
+ なので、DBからロードしたデータの中には「password」が含まれない(nilになる)という形です。
106
+
107
+
108
+
109
+ 当然、このまま保存を実行すると、
110
+
111
+
112
+
113
+ ```
114
+
115
+ user.nickname #=> "もっち"
116
+
117
+ user.email #=> "aaa@bbb.com"
118
+
119
+ user.password #=> nil
120
+
121
+ ```
122
+
123
+
124
+
125
+ の状態でバリデーションされるため、今回のような現象に繋がります。
126
+
127
+
128
+
129
+ ちなみに、「password」をわざわざ「encrypted_password」に変換して保存するのは、セキュリティ上の理由です。

1

情報が過剰だったので整理

2021/03/04 04:08

投稿

shinoharat
shinoharat

スコア1674

test CHANGED
@@ -12,19 +12,9 @@
12
12
 
13
13
  ```diff
14
14
 
15
- # 修正例1:Rails 標準の機能を利用する場合
16
-
17
15
  - validates :password, format: { 略 }
18
16
 
19
17
  + validates :password, format: { 略 }, allow_nil: true
20
-
21
-
22
-
23
- # 修正例2:devise の機能を利用する場合
24
-
25
- - validates :password, format: { 略 }
26
-
27
- + validates :password, format: { 略 }, if: :password_required?
28
18
 
29
19
  ```
30
20