使用非整数主键加入两个模型之间的关系不工作

Posted

技术标签:

【中文标题】使用非整数主键加入两个模型之间的关系不工作【英文标题】:Join with relation between two models not working using non integer primary keys 【发布时间】:2017-09-25 07:37:34 【问题描述】:

我有两个模型:HolidayHolidayInfo。如下所示:

Holiday

class Holiday extends Model

    protected $table = 'holidays';
    protected $primaryKey = 'holiday_id';
    public $timestamps = false;
    public function dates()
        return $this->hasOne('App\HolidayDates', 'holiday_id');
    
    public function images()
        return $this->hasMany('App\HolidayImages', 'holiday_id');
    
    public function info()
        return $this->hasOne('App\HolidayInfo', 'holiday_id');
    
    public function pricing()
        return $this->hasOne('App\HolidayPricing', 'holiday_id');
    

HolidayInfo

class HolidayInfo extends Model

    protected $table = 'holiday_info';
    public $timestamps = false;
    protected $primaryKey = 'holiday_id';
    public function holiday()
        return $this->hasOne('App\Holiday', 'holiday_id');
    

我的桌子:

如何在我的控制器中利用这些模型相互关联,同时使用简单的 where 子句?换句话说,HolidayInfo 和 Holiday 一样有一些我需要的信息,但是以某种方式执行连接然后执行 where 语句来缩小数据范围会更有效。

这是我尝试过的,但它没有返回正确的数据:

$holidays = Holidays::with('info')->get();

这是返回的内容 - 正如您所见,“信息”返回 null。

我还尝试按照 iCoders 的建议添加条件:

Holidays::where('country', $country)->with('info')->get();

返回以下提示连接尚未执行:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'country' in 'where clause' (SQL: select * from holidays where country = australia)

国家/地区是“holiday_info”表的一部分。

但是;执行此查询会从假日信息表返回我需要的数据,但它会遗漏假日表数据。

$holiday_info = Holidays::find(0)->info()->where('country', $country)->get();

运行以下后,出现了 60 多个结果,所以 SQL 可以正常工作,只是 laravel 不行:

SELECT * from holidays JOIN holiday_info ON holidays.holiday_id = holiday_info.holiday_id

如何将模型/关系及其数据结合起来,以便在一个地方使用它?

【问题讨论】:

为了让你走到这一步,我想你已经尝试了一些方法。也许你可以分享你是如何尝试的,这样回答的人就可以给出具体的答案,避免“给”那些“尝试”的人。 @OmisakinOluwatobi 完成 :) 【参考方案1】:

Yo已经在Holiday模型中添加了关系

public function info()
        return $this->hasOne('App\HolidayInfo', 'holiday_id');
    

你可以用with做这样的事情

Holiday::where(your condition)->with('info')->get();

更新

   public function info()
        return $this->hasOne('App\HolidayInfo', 'holiday_id','holiday_id');
    

如果您没有对表字段使用 laravel 约定,那么您将主键和外键传递给关系

有一个关系

hasOne($related, $foreignKey, $localKey )

【讨论】:

你确定你在信息表中有假期ID 是的,先生当然可以。我很快就会打印我的数据库 完成 :) 检查原帖 嗨 iCoders,仍然无法正常工作 - 我之前尝试过,这就是为什么我仍然如此困惑。变量转储:puu.sh/xJ1Un/596423120a.png 控制器:puu.sh/xJ1Ys/c79a165656.png 感谢您的帮助:) 你在info中是否有很多与假期相关的记录。如果是这种情况,请尝试hasMany并检查【参考方案2】:

感谢@iCoders 帮我破案。

问题是 public $incrementing = false; 应该在 Holiday 模式中设置,因为它是一个非整数主键。

【讨论】:

@iCoders 感谢您的帮助 - 但没有 100% 解决问题(尽管它帮助我解决了问题 :))。这一个班轮会帮助很多人,所以我会把它留在这里以供参考。我会将此标记为解决方案(如果可以),再次感谢!【参考方案3】:

只用雄辩

$holidays = Holiday::where(your condition)->with("info")->get();

然后在获取信息的价值时,只需使用:

foreach($holidays as $holiday)
    $holiday->info->youInfoFieldHere

【讨论】:

很多查询会使用这种方法运行,在这种情况下,eager-loading 会更有效,你不这么认为吗? @OmisakinOluwatobi 是正确的。我已经更新了答案

以上是关于使用非整数主键加入两个模型之间的关系不工作的主要内容,如果未能解决你的问题,请参考以下文章

在 Sequelize 中从关联创建复合主键

两个不同服务器之间的数据库关系

关系数据模型的范式

Laravel 加入 Auth 表

如何处理Rails加入表关系删除?

具有多列主键的 Laravel 模型