【问题标题】:Laravel Eloquent Relationship: misunderstanding them?Laravel 雄辩的关系:误解他们?
【发布时间】:2019-06-01 23:30:09
【问题描述】:

美好的一天!我认为我做错了什么或者我误解了 Eloquent 的做法。

我有三张桌子。

  1. 订单{市、县}
  2. 城市 { id, name }
  3. 县 { id, name }

我正在使用 Laravel Eloquent 一对多反向关系对这些表执行查询。 orders.city 拥有cities 的一个id,orders.county 拥有counties 的一个id。下面是我的模型的代码。

应用\订单

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Orders extends Model
{
    /*
    *   Table name
    */
    protected $table = 'orders';

    /*
    *   Get county
    */
    public function county()
    {
        return $this -> hasOne('App\Counties', 'id', 'county');
    }

    /*
    *   Get city
    */
    public function city()
    {
        return $this -> hasOne('App\Cities', 'id', 'city');
    }

}

应用\县

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Counties extends Model
{
    protected $table = 'account_county';
    public $timestamps = false;

    /*
    *   Counties relationship
    */
    public function county()
    {
        return $this -> belongsTo('App\Orders', 'county', 'id');
    }
}

应用\城市

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Cities extends Model
{
    protected $table = 'account_city';
    public $timestamps = false;

    /*
    *   City relationship
    */
    public function city()
    {
        return $this -> belongsTo('App\Orders', 'city', 'id');
    }
}

当我在 Tinker 中执行以下操作时:$order = App\Orders::with(['city', 'county']) -&gt; first();

....我得到以下响应:

App\Orders {#3042
     county: App\Counties {#3041
       id: 23,
       name: "Argeș",
     },
     city: App\Cities {#3046
       id: 6924,
       name: "Argeșelu",
     },
   }

现在当我运行以下代码时:$order -&gt; city

我收到以下回复:

"6924"

当我执行以下代码时:$order -&gt; City

我得到了整个收藏:

App\Cities {#3046
       id: 6924,
       name: "Argeșelu",
     },

为什么我需要将属性的第一个字母大写才能获取集合实例?在documentation 中,它声明我应该直接使用动态属性名称:$order -&gt; city 但是在我的情况下,这将返回原始字符串 ID 而不是集合实例。我错过了什么吗?我担心性能和良好实践的原因。如果这是一个不好的问题,或者已经在其他地方解释过,我深表歉意。

【问题讨论】:

    标签: php laravel eloquent relationship


    【解决方案1】:

    由于您对数据库字段和关系使用的命名约定,您遇到了这个问题。

    从数据库表中加载数据时,会将您从数据库中提取的每个字段分配给模型上的属性。这些是通过 PHP 的 __get 和 __set 魔术方法检索的,基于数据库字段的名称。所以$order-&gt;city 实际上是在该表的行上获取数据库字段的值。

    这里需要注意的是city作为属性名是区分大小写的,这就引出了下一个问题。

    当您在模型上调用$order-&gt;City 时(注意大小写),它首先查找名为City 的数据库字段属性。由于区分大小写,它无法找到该名称的数据库字段。

    Eloquent 做的下一件事是检查是否有一个名为city 的关系函数。注意情况。 PHP 类函数区分大小写,因此您可以定义一个名为city 的函数并将其称为City()。所以当你请求$order-&gt;City时,它会调用该名称的关系函数并返回数据库结果。

    这就是当您调用City 而不是city 时获得正确结果的原因。

    要解决此问题,我建议将您的关系字段 citycounty 重命名为更标准的(对于 Eloquent)值 city_idcounty_id。这不仅可以减少您的困惑,还可以从 Eloquent 的一些内置功能中受益,让您的生活更轻松。


    除此之外,$order-&gt;city 以字符串形式返回的原因是 Eloquent 按照惯例处理数据库字段的方式。它通常不会读取模式来查看数据类型,但通常会将所有内容视为字符串,除非您将其显式转换为 PHP 类型,或者它符合特定的命名约定。例如,Eloquent 会假设任何以_id 结尾的字段都是一个数字,并默认将其视为整数。因此,将 city 重命名为 city_id 会自动为您解决此问题。

    此外,请检查您的整体关系。似乎你在城市和县都有BelongsTo 关系会更好。

    【讨论】:

      猜你喜欢
      • 2017-05-16
      • 2015-03-14
      • 2018-11-28
      • 2015-01-11
      • 2021-06-03
      • 2020-03-26
      • 1970-01-01
      相关资源
      最近更新 更多