php - 如何在 Laravel 中设置 Eloquent 关系属于通过另一个模型?

标签 php laravel eloquent

我有一个模型列表,它通过它的belongsTo('Model') 关系继承应该本质上属于其对应模型所属的制造商。

这是来自我的列表模型:

    public function model()
    {
        return $this->belongsTo('Model', 'model_id');
    }

    public function manufacturer()
    {
        return $this->belongsTo('Manufacturer', 'models.manufacturer_id');
        /*
        $manufacturer_id = $this->model->manufacturer_id;
        return Manufacturer::find($manufacturer_id)->name;*/
    }

和我的制造商模型:
public function listings()
{
    return $this->hasManyThrough('Listing', 'Model', 'manufacturer_id', 'model_id');
}

public function models()
{
    return $this->hasMany('Model', 'manufacturer_id');
}

我可以在 View 中回显 $listing->model->name,但不能回显 $listing->manufacturer->name。这会引发错误。我尝试在 Listing 模型中注释掉 2 行只是为了获得效果,然后我可以 echo $listing->manufacturer() 并且这会起作用,但这并不能正确建立它们的关系。我该怎么做呢?谢谢。

修订上市模型(感谢回答者):
    public function model()
    {
        return $this->belongsTo('Model', 'model_id');
    }

    public function manufacturer()
    {
        return $this->belongsTo('Model', 'model_id')
            ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id');
    }

最佳答案

我找到了一个解决方案,但它不是非常简单。我已经在下面发布了它,但我首先发布了我认为更好的解决方案。

您不应该能够直接从列表中访问制造商,因为制造商仅适用于模型。尽管您可以从列表对象中预先加载制造商关系,但请参见下文。

class Listing extends Eloquent
{
    public function model()
    {
        return $this->belongsTo('Model', 'model_id');
    }
}

class Model extends Eloquent
{
    public function manufacturer()
    {
        return $this->belongsTo('manufacturer');
    }
}

class Manufacturer extends Eloquent
{
} 

$listings = Listing::with('model.manufacturer')->all();
foreach($listings as $listing) {
    echo $listing->model->name . ' by ' . $listing->model->manufacturer->name;
}

为了使您要求的解决方案起作用,需要花费一些时间。解决方案如下所示:
public function manufacturer()
{
    $instance = new Manufacturer();
    $instance->setTable('models');
    $query = $instance->newQuery();

    return (new BelongsTo($query, $this, 'model_id', $instance->getKeyName(), 'manufacturer'))
        ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id')
        ->select(DB::raw('manufacturers.*'));
}

我首先处理查询并从中构建响应。我想要创建的查询是这样的:
SELECT * FROM manufacturers ma
    JOIN models m on m.manufacturer_id = ma.id
WHERE m.id in (?)

通常通过执行 return $this->belongsTo('Manufacturer'); 创建的查询
select * from `manufacturers` where `manufacturers`.`id` in (?)
?将替换为 manufacturer_id 的值列表中的列。此列不存在,因此将插入单个 0,并且您永远不会返回制造商。

在我想重新创建的查询中,我受到了 models.id 的约束。 .通过定义外键,我可以在我的关系中轻松访问该值。于是关系变成了
return $this->belongsTo('Manufacturer', 'model_id');

这会产生与之前相同的查询,但会填充 ?与model_ids。所以这会返回结果,但通常是不正确的结果。然后我打算更改我从中选择的基表。这个值是从模型派生出来的,所以我把传入的模型改成了Model .
return $this->belongsTo('Model', 'model_id');

我们现在已经模仿了模型关系,所以很好,我还没有真正到任何地方。但至少现在,我可以连接到制造商表。所以我再次更新了关系:
return $this->belongsTo('Model', 'model_id')
    ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id');

这让我们更近了一步,生成了以下查询:
select * from `models` 
    inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id`
    where `models`.`id` in (?)

从这里开始,我想将我查询的列限制为制造商列,为此我添加了选择规范。这使关系变为:

返回 $this->belongsTo('Model', 'model_id')
->加入('制造商','manufacturers.id','=','models.manufacturer_id')
->select(DB::raw('manufacturers.*'));

并得到了查询
select manufacturers.* from `models` 
    inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id`
    where `models`.`id` in (?)

现在我们有一个 100% 有效的查询,但从关系中返回的对象类型是 Model不是 Manufacturer .这就是最后一点诡计出现的地方。我需要返回一个 Manufacturer, but wanted it to constrain by the型号 table in the where clause. I created a new instance of Manufacturer and set the table to模型`并手动创建关系。

需要注意的是,保存不起作用 .
$listing = Listing::find(1);
$listing->manufacturer()->associate(Manufacturer::create([]));
$listing->save();

这将创建一个新的制造商,然后更新 listings.model_id到新制造商的 ID。

关于php - 如何在 Laravel 中设置 Eloquent 关系属于通过另一个模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26327965/

相关文章:

php - ActionScript 错误 - 1086 : expecting a semicolon before left curly brace?

php - 在数据表中列出 [Laravel] [查询生成器]

php - 两列中同一表中 Eloquent 多个外键

PHP session 困惑

php - 为 foreach() 提供的 undefined variable 和无效参数

php - 使用 Route::is() 检查路由是否为主页

laravel - 如何在同一台服务器上创建另一个 Redis 服务器实例(由 Laravel Forge 管理)

php - Laravel 工厂关系......尊重 create() 或 make()

php - 使用 Eloquent ORM 执行 MYSQL 事务

php - 通过浏览按钮选择仅图像上传