簡體   English   中英

Laravel與whereColumn條件的關系

[英]Laravel relationship with whereColumn condition

看來我正在嘗試做一些非常復雜的事情或以錯誤的方式解決這個問題。 我似乎無法在網上找到與我在這里所做的類似的任何事情。 我正在嘗試查詢相關表中的列等於 model 表中的列的關系。

鑒於下表

| entity
============
id
...

| foo
============
id
entity_id
type_id
...

| baz
============
id
entity_id
type_id
...

| type
============
id
...

和型號

class Entity extends Model 
{
    public function baz()
    {
        $this->hasMany( Baz::class );
    }


    public function foo()
    {
        $this->hasMany( Foo::class );
    }
    //...
}


class Foo extends Model 
{

    public function entity()
    {
        $this->belongsTo( Entity::class );
    }

    public function type()
    {
        $this->belongsTo( Type::class );
    }
    
    //...
}


class Baz extends Model {
    
    public function entity()
    {
        $this->belongsTo( Entity::class );
    }


    public function type()
    {
        $this->belongsTo( Type::class );
    }
    
    //...
}


class Type extends Model 
{
    //...
}

我有以下代碼工作,但在不同的上下文中 Foo 和 Baz 都使用 $type_id 過濾

public function controllerActionWorking( Request $request, $type_id )
{

    // I'm using this in another place to get rows of Foo with type_id == $type_id.  Including Related Baz which also have type_id == $type_id
    $results = Foo::with( 
        [ 
            'entity.baz' => 
            function( $query ) use ($type )
            {
                return $query->where( 'type_id', $type->id ))
            }
        ])
        ->where( 'type_id', $type_id )
        ->get()
        
       // ....
}

現在我需要所有 Foo 記錄和與 Foo 實體相關的 Baz 記錄,其中 Baz.type_id 等於 Foo 記錄的 type_id。 這是無效的代碼,但是我首先開始嘗試這樣的事情。

public function controllerActionHelpWanted( Request $request )
{

    $results = Foo::with( 
        [
            'entity.baz' =>
            function( $query )
            {
                
                // Here I need to verify the entity.baz.type_id = foo.type_id                
                
                // the following does NOT work
                // I get errros that 'foo'.'type_id' does not exist
                return $query->whereColumn( 'foo.type_id', 'baz.type_id' ) 
            })
        ])
        ->get()

    // .....

}

我可以使用類似這樣的join()

$results = Foo::with( 'entity' )
    ->join( 
        'baz',
        function($join)
        {
            return $join->on( 'foo.entity_id', 'baz.entity_id' )
                ->on( 'foo.type_id', 'baz.type_id' );
        })
    ->get()

這將返回一個 Foo 的實例,該實例具有兩個表的組合屬性。 它也失去了 'entity.baz' 嵌套關系。 這在下游代碼中很重要。

我可以$results->map()在查詢后過濾“entity.baz”關系。 如果可能的話,我寧願避免對性能的影響。

好像我在這里遺漏了一些東西。 任何幫助/建議表示贊賞。

當名稱為 foo/baz 且未應用邏輯引用時,難以閱讀。 看起來像多對多關系,您可以在其中應用 pivot。

public function products()
{
    return $this->belongsToMany(Product::class)
        ->withPivot('quantity', 'price'); // joins data from intermediate table
}

Pivot 表的查詢方式為:$obj->pivot->quantity;

就你把你的問題包裝成 faz/baz/entity 而言,它對我來說變得很抽象,仍然:)

讓我們嘗試讓您的查詢更加模型方面:

class Foo extends Model
{
    use HasFactory;

    public function entity()
    {
        return $this->belongsTo(Entity::class, 'entity_id', 'id');
    }

    public function scopeTypes($query, $type_id)
    {
        return $query->where('type_id', $type_id);
    }

    public function scopeWithBazes($query, $type_id)
    {
        /* @var $query Builder */
        return $query->join('bazs', function($type_id) {
            return self::where('type_id', $type_id);
        });
    }
}

在 controller 里面我可以做:

class TestController extends Controller
{
    public function index(Request $request)
    {
        $foos = Foo::query()->withBazes(1)->get();

        foreach($foos as $foo)
            dd($foo->baz_name); // i placed baz_name in Baz table for test
    }
}

好吧,缺點是表是連接的。 它被連接是因為你沒有任何中間表,所以你需要使用連接等。

Foo::types($type) 將返回給定類型的 foos 集合。 Foo::bazTypes($type) 將返回連接表。

不過,當您省略中間表時,會出現這類問題,查詢會變得更加復雜,但數據庫的健壯性會有所下降。

如果您能夠將命名抽象化為“真正的”問題,也許人們會更多地使用它。 只需制作 foo => invoice、baz => address 等,因此也許您會為您的場景找到更好的數據庫模式。 有時無論如何你都會遇到多個查詢,但這總是值得一問的:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM