LaravelのDB検索した後のデータの扱い時、getとfirstの扱いが曖昧だったため確認して見ました。
前提
例えばid、title、bodyを持つpostデータのテーブルがあったとします。
で、そのidを持つpostを検索し、そのpostのtitleを返すコントローラーを作りたいとします。
最初の状態。get()でデータを取得した。
public function post($id){
$post = Post::where('id',$id)->get();//whereで引数の$idと同一のpostを検索。
Log::debug($post);//このログの出力:[{"id":5,"title":"hoge","body":"hoge"}]
return $post->title;
}
//詳細は省略しております
が、上記のように「$post->title」を返そうとするとそんなプロパティないよ!と怒られエラーとなりました。
local.ERROR: Property [title] does not exist on this collection instance.
なぜだ?ちゃんと出力データの中には「title」あるのに!と思ってgetやfirstの取って来ているデータを調べました。
原因
で、get()ではなくfirst()にするとうまくいったので、
それぞれのwhere直後の$postを見てみると、こんな状態になってました。
first()で取得した時のデータ
{"id":5,"title":"hoge","body":"hoge"}
get()で取得した時のデータ
[{"id":5,"title":"hoge","body":"hoge"}]
何が違う?
get()の方もfirstの方も、今回「id」でwhere検索しているので、1件しか取得してないのですが
getの方は[]で囲われています。
例えば
[
{"id":9,"title":"hoge","body":"hoge"},
{"id":1o,"title":"fuge","body":"fuge"},
]
のように数件取得して、foreachで一件ずつに「->title」で呼び出すなら問題ない、
複数件前提のデータということになります。
今回のように1件だけ決めうちで取りたいならfirst()を使うべきでした。
こうするとうまく動きました!
$post = Post::where('id',$id)->first();