質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

3回答

942閲覧

【Laravel5.4】Controllerでリレーションしている値を取得。

tonari

総合スコア45

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2017/07/27 13:41

目的:Controllerで、Main::all()に対するリレーションしている値を全件取得したいと考えています。(withメソッドはエラーが出ました。)

やっていること:
リンク内容コチラを参考に検索機能を作っています。
②hasOneでMainというtable(Model)にTestというtable(Model)、SubTestというtable(Model)をリレーションしています。
③Main::all()の値をviewに渡しforeachで一覧表示しています。その際リレーションしたカラムも取り出せています。(これをController側でもしたいです。)

リレーション自体は↓の様にしたら出来ました。

-MainController.php- public function index(Request $request) { $mains = $this->main->find(1)->tests;//testsはModelでリレーションを定義した関数名です $mains = $this->main->find(1)->subtests;//subtestsはModelでリレーションを定義した関数名です }

今回したいのはこんな感じのことです↓findなどで絞らずにやりたいのでこんな感じに・・・

-MainController.php- public function index(Request $request) { $inputs = $request->all();//viewからの値を$inputsに入れてます。 if ($input['test']) { $posts = $this->main->all()->tests->where('test', 'LIKE', "%$input['test']%")->all(); //mainと紐づいているtestsの中のtestと言うカラムに検索をかけたいと考えています。 }elseif($input['subtest']){ $posts = $this->main->all()->subtests->where('subtest', 'LIKE', "%$input['subtest']%")->all(); }else{ $posts = $this->main->all(); } return view('test.index', compact('posts')); }

やはりこれだとfindがないのでtestsやsubtestsが取れませんでした。
all()以外で全件取得の方法が分からずここで迷走。

試したこと:↓Viewの様にController側でforeachしてリレーションした値を取得しようと思いましたが最初の一つしか取れませんでした(惜しいのかもしれないと考えています。)

-MainController.php- $mainss = $this->main->all(); foreach($mains as $main) { $dd = $main->tests->test; } dd($dd);

よろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

$posts = $this->main->all()->tests->where('test', 'LIKE', "%$input['test']%")->all();
//mainと紐づいているtestsの中のtestと言うカラムに検索をかけたいと考えています。

色々勘違いが重なっているようなので、いくつか。

条件指定後のデータ取得では、all() ではなく get() を使う

all()は内部的にquery()->get()と呼び出すのと等価です。
つまりwherewithなどを使わず、単純に全件取得するときに利用します。
今回のようにクエリビルダにより条件を絞ったりする場合は、
all()ではなくget()を、最後に使って下さい。

->tests と ->tests() は違う

->testsと書くと、内部的にget()やfirst()が呼び出され、結果の取得を意味します。
やりたいことは、更なるwhereメソッドによる条件の追加でしょうから、
続いてクエリビルダを使えるように->tests()と書いてください。
括弧がつくのとつかないのでは、意味が全く異なります。

リレーションテーブルへの条件指定の間違い

最初のwhereの書き方では
「Testテーブルのtestカラム」に対してではなく
「Mainテーブルのtestカラム」に検索しに行くため
Mainテーブルにtestというカラムは無いという意味合いのエラーが発生するかと思います。
withを使う場合の、リレーション先に対する条件は以下のように書けます。

PHP

1$posts = $this->main 2 ->with(['tests' => function ($query) { 3 $query->where('test', 'LIKE', "%$input['test']%"); 4 }]) 5 ->get();

リレーションの種類(hasOne)を勘違いしている可能性がある

Controller側でforeachしてリレーションした値を取得しようと思いましたが最初の一つしか取れませんでした

hasOneはリレーション先のテーブルに対応するデータが1件のみの時に使います。
ですから、データがあったとしたら1件だけ取れるのが正常です。
複数取れることを想定しているのであれば、そのリレーションはhasOneではありません。
(例えば、MainからTestがhasManyで、TestからMainにbelongsTo、等)
これに関しては想像を含むので、認識違いであったら申し訳ありません。


最後に、クエリビルダの使い方なら以下のページが参考になるかと思います。
https://readouble.com/laravel/5.4/ja/queries.html

投稿2017/07/27 20:09

Archsted

総合スコア452

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tonari

2017/07/28 01:13

ありがとうございます!
guest

0

ベストアンサー

リレーションはteststests()で結果が変わります。
https://readouble.com/laravel/5.4/ja/eloquent-relationships.html#relationship-methods-vs-dynamic-properties

この場合は

$posts = $this->main->tests()->where('test', 'LIKE', "%$input['test']%")->all();

Eagerローディングなら

$posts = $this->main->with('test')->where('test', 'LIKE', "%$input['test']%")->all();

withでエラー出るならどこかの書き方を間違ってます。

投稿2017/07/27 14:02

kawax

総合スコア10377

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tonari

2017/07/28 02:04

ありがとうございます! withの値を $posts = $this->main->with('test')->get(); から $posts = $this->main->with('tests')->get(); にし、dd($posts);をしてみたところtests()のtestというカラムは、 #itemsの中のMainの中の #relationsの中の”tests”のなかにありました! しかし$posts = $this->main->with('tests')->where('test', 'LIKE', "%$input['test']%")->get();とすると、 SQLSTATE[42703]: Undefined column: 7 ERROR: 列"test"は存在しません と言うエラーが出ました。取得できてるはずなのにこれは何故出るのでしょうか?
guest

0

EloquentはORMとクエリビルダーが連携したところ等に独自の考え方があるのでララ帳さんのサイトがフレームワークの一通りの機能を解説しているので一度通しで学習してから開発を始めると理解が早いかと思います。
はじめてのLaravel 5.1

Eloquentは最終的にはSQL文を発行してDBとやり取りを行うので、データが取れない場合は発行されるSQL文を確認することも重要です。DB取得処理の手前で\DB::enableQueryLog()を、DB取得処理の後に\DB::getQueryLog()で取得できます。

\DB::enableQueryLog(); $mains = $this->main->find(1); dd(\DB::getQueryLog());

投稿2017/07/28 07:38

aro10

総合スコア4106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問