【问题标题】:Eloquent - Get single model when using morphMany in polymorphic relationshipEloquent - 在多态关系中使用 morphMany 时获取单个模型
【发布时间】:2021-06-27 00:34:48
【问题描述】:

我有一个像这样的Contact 命名模型:

class Contact extends Model
{
    public    $timestamps = false;
    protected $primaryKey = 'contact_id';
    
    protected $fillable = [
        'tel', 'fax', 'email', 'mob', 'address'
    ];

    public function contactable ()
    {
        return $this->morphTo();
    }
}

上述模型可以属于其他模型,例如House这样的模型:

class House extends Model
{
    protected $primaryKey = 'house_id';

    public function contact ()
    {
        return $this->morphMany('App\Contact', 'contactable');
    }
}

每个House只能有一个相关的Contact,但是由于Contact模型可以与其他模型相关,所以我必须定义多态关系。

现在,当我想获得特定 House 模型的相关 Contact 模型时,即返回一个 Contact 数组(只有一个元素)把它作为一个简单的对象模型;例如:

public function edit (\App\House $house)
{
    $house = $house->load('contact');
    
    return $house;
    
    return view('admin/pages/house/house-edit', compact('house'));
}

结果是这样的:

{
    "house_id": 6,
    "title": "testا",
    "header": "0f74e9aa891bcc6fb84aa744721d9692.jpg",
    "type": "sara",
    "creator": 1,
    "created_at": "2016-07-26 15:19:31",
    "updated_at": "2016-07-26 15:19:31",
    "contact": [
        {
            "contact_id": 1,
            "tel": "1",
            "fax": "2",
            "email": "3",
            "mob": null,
            "contactable_id": 6,
            "contactable_type": "App\\House"
        }
    ]
}

我尝试在关系上使用first() 方法:

public function contact ()
{
    return $this->morphMany('App\Contact', 'contactable')->first();
}

但是我收到了这个错误:

调用未定义的方法 Illuminate\Database\Query\Builder::addEagerConstraints()

这个问题的解决方法是什么?

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    我一直在检查是否有人可以给出答案,但由于没有人可以,我非常疯狂地猜测这有一定的工作机会:

    public function contactRelation()
    {
        return $this->morphMany('App\Contact', 'contactable');
    }
    
    public function contact()
    {
        $this->load('contactRelation');
    
        return $this->contactRelation->first();
    }
    

    基本上我认为你不能在变形关系上调用 first() 方法,所以如果你先进行变形然后尝试先调用结果,它可能会起作用.

    请注意,您的控制器中不再需要$house = $house->load('contact');,只需尝试像这样访问关系:$house->contact();

    【讨论】:

    • 感谢@TheFallen,根据您的解决方案,我添加了一个名为getContactAttribute 的访问器并将其添加到模型的$appends 属性中,以简化对模型联系人的访问。现在当我得到一个 House 模型时,相关的联系模型作为一个简单的属性附加到它上面。
    【解决方案2】:

    有一种方法可以解决这个问题,而无需创建两个函数。

    一个例子可以是:

    // House.php
    public function contact()
    {
    
        return Contact
    
            ::where('contactable_id', $this->id)
    
            ->where('contactable_type', 'App\\House')
    
            ->first();
    
    }
    

    也许您必须更改一些名称。

    希望这会有所帮助:)

    编辑

    上面的方案只能这样调用:

    $house->contact()

    如果您希望以“正常”方式使用它 ($house->contact->first()),您应该删除链末尾的 ->first()

    【讨论】:

      【解决方案3】:

      你可以使用morphOne关系

      public function contact ()
      {
          return $this->morphOne('App\Contact', 'contactable');
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-12
        • 1970-01-01
        • 1970-01-01
        • 2016-09-01
        • 2018-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多