やったこと
deviseなどのgemを使わずユーザー登録機能をrailsとvueで実装
ハマったこと
ユーザー登録フォームに入力してPOSTした時、:userの中にpasswordとpassword_confirmationの値が入らず(ネストせず)かなり苦戦。
具体的にはこんな感じ。
理想形
Parameters: {"user"=>{"name"=>"hogehoge", "email"=>"fugafuga@test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}
NG形
Parameters: {"name"=>"", "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "user"=>{"name"=>"", "email"=>""}}
passwordとpassword_confirmationだけuserの中に入ってこない!!
まあNG形の場合でもコントローラーのストロングパラメーターで
private
def user_params
params.permit(:name, :email, :password, :password_confirmation)
end
とすれば大丈夫なんだけど、どうしてもカッコよくこう書きたい!
private
def user_params
params.fetch(:user, {}).permit(:name, :email, :password, :password_confirmation)
end
vueで書くとhas_secure_password効かないのか〜?とか、formの書き方が悪いのか〜?とか、とにかく色々と原因を考えまくって時間を浪費したこと浪費したこと。
Vueの書き方
先にNGだった書き方から。(js部分のみ。かなり省略してます)
NGの書き方
import axios from 'axios';
export default {
data: () => ({
user: {
name: '',
email: '',
password: '',
password_confirmation: '',
},
}),
methods: {
createUser: function() {
axios
.post('/api/v1/users', this.user)
.then(response => {
var res = response.data;
this.$router.push({ name: 'home' })
})
.catch(error => {
if(error.response.data && error.response.data.errors) {
this.errors = error.response.data.errors;
}
})
},
これだとNG形になります。
理想形のパラメーターが返ってくる書き方
import axios from 'axios';
export default {
data: () => ({
name: '',
email: '',
password: '',
password_confirmation: '',
}),
methods: {
createUser: function() {
axios
.post('/api/v1/users', { user: { name: this.name, email: this.email, password: this.password, password_confirmation: this.password_confirmation }})
// 以下、同じなので省略
POSTする時に、こうやって明示的に書けばOKだった!
どうしても納得いかないのが、NGの時もnameとemailはちゃんとネストされてたってこと。
passwordとpassword_confirmationは、テーブルのカラムに存在しないから取れなかったと思うんだけど、has_secure_passwordを書いててもダメなもんかい
初歩的な実装に、ものすごい時間がかかってしまったというお話でした。
ではまた!