【问题标题】:Querying Laravel Relationship查询 Laravel 关系
【发布时间】:2015-05-12 09:38:27
【问题描述】:

我试图从早上开始进行一个查询工作,但无法让它工作我有两张桌子摄影师和评论请看一下结构,然后我会在底部提出问题:

评论表:

id int(10) unsigned -> primary key 
review text
user_id int(10) unsigned foreign key to users table
user_name varchar(64) 
photographer_id int(10) unsigned foreign key to photographers table 

摄影师表:

id int(10) unsigned -> primary key
name text
brand text
description text
photo text
logo text
featured varchar(255)

摄影师模特:

class Photographer extends Model
{

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

评论模型:

class Review extends Model
{
public function photographers()
{
    return $this->belongsTo('\App\Photographer');
}
}

我查询记录的逻辑

$response = Photographer::with(['reviews' => function($q)
{
    $q->selectRaw('max(id) as id, review, user_id, user_name, photographer_id');
        }])
        ->where('featured', '=', 'Yes')
        ->get();

问题是:我想获取评论表中至少有一条评论的所有摄影师,我也想只获取一条最新的评论,我可能有多个摄影师的评论但是我只想要一个。

【问题讨论】:

  • 它与这个问题的答案无关,但我会将Review::photographers 方法重命名为 Review::photographer,因为它是“属于”关系,并且只会返回一个结果。 (语义)

标签: eloquent laravel-5 relationship


【解决方案1】:

我会在您的 Photogrpaher 类中添加另一种关系方法:

public function latestReview()
{
    return $this->hasOne('App\Review')->latest();
}

然后你可以调用:

Photographer::has('latestReview')->with('latestReview')->get();

注意事项:

  • 查询构建器上的latest() 方法是orderBy('created_at', 'desc') 的快捷方式。您可以通过传递参数来覆盖它使用的列 - ->latest('updated_at')
  • with 方法在最新评论中加载。
  • has 方法仅查询至少有一项指定关系的摄影师

看看Has Queries in Eloquent。如果您想进一步自定义 has 查询,whereHas 方法将非常有用

如果你有兴趣

您可以将查询方法添加到关系方法的结果中。关系对象有一个查询构建器对象,它们会将自身不存在的任何方法传递给该对象,因此您可以将关系用作该关系的查询构建器。

在 Eloquent ORM 模型的关系方法中添加查询范围/参数的优势在于:

【讨论】:

    【解决方案2】:

    您需要的最好通过对reviews 关系的范围查询来完成。

    将此添加到您的评论模型中:

    use Illuminate\Database\Query\Builder;
    use Illuminate\Database\Eloquent\Model;
    
    class Review extends Model {
        public function scopeLatest(Builder $query) {
            // note: you can use the timestamp date for the last edited review,
            // or use "id" instead. Both should work, but have different uses.
            return $query->orderBy("updated_at", "desc")->first();
        }
    }
    

    然后就这样查询:

    $photographers = Photographer::has("reviews");
    foreach ($photographers as $photographer) {
        var_dump($photographer->reviews()->latest());
    }
    

    【讨论】:

    • 它说调用未定义的方法 Illuminate\Database\Eloquent\Collection::latest()
    • ->reviews 应该是 ->reviews(),我的错。
    • 我认为你需要在has 之后调用get() 来执行查询(如果你正在做我认为你正在做的事情)。并且可能在latest() 之后
    • (我应该注意我实际上并没有以任何方式测试这个,因为我无法访问我的开发环境)
    猜你喜欢
    • 2013-10-03
    • 2017-07-19
    • 2021-05-27
    • 2020-03-16
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多