web-dev-qa-db-ja.com

addSelect()BuilderメソッドがLaravel

これらのモデルがあるとしましょう:

ユーザーモデル

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'User';

    protected $fillable =
    [
       'username', 'favoriteColor'
    ];          

    public function flights()
    {
        return $this->hasMany('App\Flight');
    }
}

フライトモデル

namespace App;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'Flight';

    protected $fillable =
    [
       'flightName', 
    ];              
}   

私はこれをするときはいつでも、熱心なロードで何かをしようとしています:

$usersWithFlights = User::with(['flights'])->get();

私は次のようなデータを取得します:(問題ない場合、私が期待するものです)

{
    "userID": 1,
    "favoriteColor": green
    "flights": 
    [
       {
           "flightID": 2240,
           "flightName" : "To Beijing fellas"
       },
       {
           "flightID": 4432,
           "flightName" : "To Russia fellas"
       },       
    ]
}

しかし、私は次のようにselect rawを使用して列を追加したいと思います(1 as numberがどれほどばかげているかを考えないでください。これは例のためだけです。

$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();

私はこのようなデータを取得します:

[
    {
        "userID": 1,
        "favoriteColor": green
        "flights": []
    }
]

[〜#〜]質問[〜#〜]

AddSelect()メソッドはこの種の振る舞いのために作成されましたか?そうでない場合、これを達成するための他の回避策はありますか?

[〜#〜]ノート[〜#〜]

SelectメソッドにFlights.*, Users.*のようなものを追加できることはわかっていますが、addSelectメソッドがそのように機能するかどうかを知りたいです

8
ggderas

Selectからのデフォルト値が必要で、追加する場合は、次の構成を使用できます。

$usersWithFlights = User::with(['flights'])->select()->addSelect(DB::raw('1 as number'))->get();
19
plaha

最初にaddSelectメソッドを見てください:

_public function addSelect($column)
{
    $column = is_array($column) ? $column : func_get_args();
    $this->columns = array_merge((array) $this->columns, $column);
    return $this;
}
_

これは、既存の選択された列とマージすることによって列を追加するだけです。したがって、次のようなものを使用すると、

_$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
_

クエリは_select 1 as number from flights_になり、リレーションは親クエリの列値に依存するため、実際の列値がない場合、関連するレコードは取得されません。クエリを確認するには、次のような方法を試してください。

_\DB::enableQueryLog();
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
dd(\DB::getQueryLog());
_

また、add selectで実際の列名を使用し、関連する列を選択しない場合、たとえばaddSelect('someString')を使用すると、関連するレコードも取得されません。リレーションを作成する関連列を選択します。この場合、次のようなことを試すことができます。

_$usersWithFlights = User::with(['flights'])->addSelect(['id', 'someString']))->get();
_

テスト:

これはDB::getQueryLog()のテスト結果です。同じようなものを使用しましたが、DBのテーブルが異なります。

_Post->with('comments')->addSelect(DB::raw('1 as number'))->get();
dd(DB::getQueryLog());
_

結果:

_0 => array:3 [▼
  "query" => "select 1 as number from "posts""
  "bindings" => []
  "time" => 9.0
  ]
1 => array:3 [▼
  "query" => "select * from "comments" where "comments"."post_id" in (?)"
  "bindings" => array:1 [▼
    0 => null
  ]
  "time" => 1.0
]
_

更新:

addSelectメソッドは、いくつかの選択されたフィールドを持つクエリオブジェクトが手元にあり、後で選択リストにフィールドを追加して、次の例のようにする場合に便利です。

_$userWithFlights = User::with('flights')->select(['id', 'someColumn']);
// Some code ... 
if(SomeCondition) {
    // So, now the query will be something like this:
    // ->select(['id', 'someColumn', 'anotherField'])
    $userWithFlights->addSelect('anotherField');
}

$result =  $userWithFlights->get();
_

選択するフィールドを指定する場合は、代わりにselect($fieldsArray)を使用できます。次のようなものを試すこともできます。

_$userWithFlights = User::with('flights')->get(['id', 'someColumn']);
_

また、あなたはこのようなものを試すかもしれません:

_$userWithFlights = User::with(['flights' => function($query) {
    $query->select('user_id', 'flight_title');
}])->get(['id', 'someColumn']);
_
4
The Alpha