Laravel雄辩的关系:误解他们了吗?

时间:2019-06-01 23:30:10

标签: php laravel eloquent relationship

美好的一天!我想我做错了什么,或者我误解了口才。

我有三个桌子。

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

我正在使用Laravel雄辩的一对多逆关系对这些表执行查询。 cities持有一个orders.county的ID,而counties持有一个<?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'); } } 的ID。下面是我的模型的代码。

应用\订单

<?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');
    }
}

应用程序\城市

$order = App\Orders::with(['city', 'county']) -> first();

当我在Tinker中执行以下操作时:App\Orders {#3042 county: App\Counties {#3041 id: 23, name: "Argeș", }, city: App\Cities {#3046 id: 6924, name: "Argeșelu", }, }

...。我收到以下答复:

$order -> city

现在,当我运行以下代码时:"6924"

我收到以下答复:

$order -> City

但是,当我执行以下代码时:App\Cities {#3046 id: 6924, name: "Argeșelu", },

我得到了整个收藏夹:

$order -> city

为什么我需要将属性的首字母大写以获取集合实例?在documentation中,它指出我应直接使用动态属性名称:var xmlSer = new XmlSerializer(typeof(List<Utilisateur>)); var xmlWriterSettings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true // need only for pretty print }; bool append = File.Exists("test.txt"); using (var streamWriter = new StreamWriter("test.txt", append)) using (var xmlWriter = XmlWriter.Create(streamWriter, xmlWriterSettings)) { xmlSer.Serialize(xmlWriter, listeUtilisateurs); streamWriter.WriteLine(); // need only for pretty print } 但是,在我的情况下,这将返回原始字符串ID,而不是集合实例。我想念什么吗?我担心性能和良好做法的原因。对于这个问题不好或者是否已经在其他地方解释过,我深表歉意。

1 个答案:

答案 0 :(得分:0)

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

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

这里要注意的一件事是city作为属性名称是区分大小写,这使我们进入下一个问题。

在模型上调用$order->City时(请注意案例),它首先查找名为City的数据库字段属性。由于区分大小写,因此找不到该名称的数据库字段。

Eloquent的下一步是检查是否存在称为city的关系函数。请注意情况。 PHP类函数不区分大小写,因此您可以定义一个名为city的函数并将其命名为City()。因此,当您要求输入$order->City时,它将调用该名称的关系函数并返回数据库结果。

这是当您致电City而不是city时获得正确结果的原因。

为解决此问题,我建议将您的关系字段citycounty重命名为city_idcounty_id的更标准(对于口才)。这不仅会减少您的困惑,而且您将从某些内置的Eloquent功能中受益,使您的生活更轻松。


此外,$order->city返回字符串的原因是Eloquent按照惯例对待数据库字段的方式。它通常不读取架构来查看数据类型,而是通常将所有内容都视为字符串,除非您将其显式转换为PHP类型,或者满足特定的命名约定。例如,Eloquent将假设以_id结尾的任何字段都是数字,并且默认情况下将其视为整数。因此,将city重命名为city_id将自动为您解决此问题。

还要检查您的整体关系。在城市和县级建立BelongsTo关系似乎会更好。