毎日更新

70日目 個人開発記 10 -firstOrCreateでハマった-

おはようございます。

今日は個人開発記「firstOrCreateでハマった」です。

めっちゃマニアックな話になりそうですが、備忘録として。

現在、SNSログイン機能を実装しています。Laravelのでは『Socialite』という便利なライブラリが用意されているので、こいつを使えばそこまで難しくなく実装することができます。

実装の参考にしているのはこの記事です。

「世界一丁寧」という謳い文句に遜色ない、素晴らしい記事です。Twitterログインはこの記事を見てればとりあえず実装できると思います。他のソーシャルアカウント(GoogleとかGithubとか)で詰まったら場合は、個別に調べればたくさんの情報がヒットします。

んで、昨日超絶に詰まったのが、Laravelの

firstOrCreate()

です。

https://search.readouble.com/?query=7.x+firstOrCreate

こいつは便利なEloquentで、「特定のキーでモデルを探し、一致したらモデルを返す、一致しなかったら新規のモデルを作成する」とい使い方ができます。

たとえば、「firstOrCreateを使ってユーザーモデルを返し、ログインさせる」というのを先ほどのSNSログインの記事を参考に実装すると、

Auth::login(User::firstOrCreate(
 ['email' => $providerUser->getName()], // 第一引数
 ['name' => $providerUser->getName(), 'twitter_id' => $providerUser->getId()] // 第二引数
)); 

のように書くことができます。

firstOrCreateの第一引数

['email' => $providerUser->getName()]

これは、ユーザーテーブルからemailをキーに、取得したemailを持つユーザーがいるかどうかの探しています。もし存在する場合はそのユーザーモデルを返す、存在しない場合は、第二引数の

['name' => $providerUser->getName(), 'twitter_id' => $providerUser->getId()]

も参照し、「email,name,twitter_idを含めた新しいユーザーモデルを返す」ということになります。

fistOrCreateを使わず同じことをやろうとするともっとコード量が多くなってしまうのですが、このメソッドは直感的だしコードもスッキリだし非常にいい感じです。

で、こいつを使ってTwitterログインを実装していたのですが、どんだけやってもtwitter_idに値が入ってくれません。新しく作成されたユーザーのtwitter_idはnullのままです。

「'twitter_id'というカラム名がいけないのか?'_'が入ってるとダメなのか?」と違うカラム名を試してみたり、「getId()でidが取得できないのか?じゃあ確実に取得できているgetName()をtwitter_idカラムに入れてみよう!」などといろんなアプローチをとりましたが、状況は変わらず。しかもエラーが出ないからタチが悪い。全く原因が分からない。

「あぁ、おれは一生twitter_idにnull以外を入れることはできないんだな…」と諦めかけていたそのとき、ふと閃きました。

「emailとnameだけちゃんと値が入るのはなんでだろう」ということをヒントに、Userモデルに

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];

という記述があったことを思い出しました。モデルを新規で作るとき、

$post = new Post();
$post = fill($request->all())->save();

みたいな登録の仕方ができるんですが、この時値が追加されるカラムは$fillableに書いてあるものだけです。

「twitter_idに値が入らなかった原因、もしやこいつでは、、、?」と試してみたところ、ビンゴでした。これにて数時間に渡る死闘は無事に終結しました。

とりあえずURL直接叩いて「同期処理」でTwitterログイン実装することはできたので、これから非同期でapi叩いてちゃんと動くか検証します。

おわり。

  • この記事を書いた人

きわっち

元食品メーカー製造マンが未経験からwebエンジニアになりました。 エンジニアとして0から成長していく過程を発信していきたいと思っています。

© 2021 きわっちのブログ Powered by AFFINGER5