使用"USING"子句与N查询进行雄辩联接

Egy*_*din 9 php mysql eloquent

我正在使用Slim Framework和Illuminate Database.
我想JOINUSINGclausa 进行查询.让我们说给Sakila数据库.图:
ER图
如何在雄辩的模型中与USING子句(不是ON)连接?

SELECT film_id,title,first_name,last_name 
FROM film_actor 
INNER join film USING(film_id) -- notice 
INNER join actor USING(actor_id) -- notice 
Run Code Online (Sandbox Code Playgroud)

我想要的是一个急切加载EXACT 1查询.在使用中所描述雄辩关系的API不符合我的期望,因为任何渴望使用关系N + 1个查询.我想减少数据库的IO.

FilmActor模型:

class FilmActor extends Model
{
    protected $table = 'film_actor';
    protected $primaryKey = ["actor_id", "film_id"];
    protected $increamenting = false;
    protected $appends = ['full_name'];

    // i need to make it in Eloquent model way, so it easier to manipulate
    public function getFullNameAttribute()  
    {
        $fn = "";
        $fn .= isset($this->first_name) ? $this->first_name ." ": "";
        $fn .= isset($this->last_name) ? $this->last_name ." ": "";
        return $fn; 
    }

    public function allJoin()
    {
        // how to join with "USING" clause ?
        return self::select(["film.film_id","title","first_name","last_name"])
            ->join("film", "film_actor.film_id", '=', 'film.film_id')  
            ->join("actor", "film_actor.actor_id", '=', 'actor.actor_id');  

        //something like
        //return self::select("*")->joinUsing("film",["film_id"]);
        //or
        //return self::select("*")->join("film",function($join){
        //    $join->using("film_id");
        //});
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,在控制器中我可以得到像这样的数据

$data = FilmActor::allJoin()  
        ->limit(100)  
        ->get();`  
Run Code Online (Sandbox Code Playgroud)

但是如果我需要添加额外的行为(比如whereorder),那就有了一个骗局.

$data = FilmActor::allJoin()
        ->where("film.film_id","1")   
        ->orderBy("film_actor.actor_id")  
        ->limit(100)  
        ->get();`  
Run Code Online (Sandbox Code Playgroud)

我需要传递表名以避免模糊字段.不好.所以我想进一步使用,我能做到

$kat = $request->getParam("kat","first_name");  
// ["film_id", "title", "first_name", "last_name"]  
// from combobox html  
// adding "film.film_id" to combo is not an option  
// passing table name to html ?? big NO

$search = $request->getParam("search","");
$order = $request->getParam("order","");
$data = FilmActor::allJoin()
        ->where($kat,"like","%$search%")   
        ->orderBy($order)  
        ->limit(100)  
        ->get();`  
Run Code Online (Sandbox Code Playgroud)

bat*_*to3 0

You can try find in code is possible to make USING JOIN, or add some proxy dictionary:

$kat_dict =  ["film_id" => "film.film_id", "title"=> 'title', "first_name" => 'first_name', "last_name" => 'last_name'];

$kat = $kat_dict[$request->getParam("kat","first_name")];
Run Code Online (Sandbox Code Playgroud)

BTW: better way is using function like Arr::get($arr, $index, $default) (See at code example)