6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Laravel】allメソッドを使うとtoSqlメソッドが使えない

Last updated at Posted at 2019-02-11

クエリビルダを使用すると、toSqlメソッドで実行されるSQLを取得することができます。

しかし、City::all()のようにallメソッドを使用した場合は、toSqlメソッドを使うことができません。

以下のエラーが出ます。

Method Illuminate\Database\Eloquent\Collection::toSql does not exist.

エラーメッセージの通りなのですが、原因を探ってみました。

allメソッドの場合

test.php
$sql_all = City::all();
var_dump(get_class($sql_all));
// エラー発生
var_dump($sql_all->toSql());

オブジェクトのクラス名を取得すると、Illuminate\Database\Eloquent\Collectionクラスが使用されていることがわかります。

addメソッド自身は、スーパークラスであるSupport\Collectionクラスに定義されています。

しかし、両クラスともtoSqlメソッドが定義されていません。
これが原因でした。

Illuminate\Support\Collection.php
/**
 * Get all of the items in the collection.
 *
 * @return array
 */
public function all()
{
    return $this->items;
}

さらに、getメソッドを使用した場合も同じエラーが出ます。

test.php
$sql_builder = DB::table('city')->get();
var_dump(get_class($sql_builder));
// エラー発生
var_dump($sql_builder->toSql());

上記のコードではEloquentを使用していないので、オブジェクトのクラス名はIlluminate\Support\Collectionになります。

エラーの理由は上記と同じです。

toSqlメソッドの場所

当のtoSqlメソッドが定義されているクラスは、Builderクラスになります。

Illuminate\Database\Query\Builder.php
/**
 * Get the SQL representation of the query.
 *
 * @return string
 */
public function toSql()
{
    return $this->grammar->compileSelect($this);
}

whereメソッドの場合

whereメソッドを使用する場合は、toSqlメソッドが使用できます。

オブジェクトのクラス名を確認すると、lluminate\Database\Eloquent\Builderクラスが使用されていると確認できます。

これはtoSqlメソッドが定義されているクラスと同じです。

test.php
$sql_where = City::where('Name', '=', 'Kabul');
var_dump(get_class($sql_where));
// 出力される
var_dump($sql_where->toSql());

コアファイルを読む良いきっかけになりました。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?