【问题标题】:Eloquent morphOne relationship doesn't limit to one relation雄辩的 morphOne 关系不限于一种关系
【发布时间】:2014-09-01 21:41:29
【问题描述】:

我遇到了 Eloquent morphOne 关系的问题,它正在创建新条目而不是更新已经存在的条目。

基本上我有许多模型(例如,假设PersonBuilding)都需要一个位置,所以我创建了一个Location 模型:

class Location extends Eloquent {

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

}

然后在我的其他模型中,我有这个:

class Person extends Eloquent {

    // ...

    /**
     * Get the person's location
     * 
     * @return Location
     */
    public function location()
    {
        return $this->morphOne('Location', 'locationable');
    }

    // ...
class Building extends Eloquent {

    // ...

    /**
     * Get the building's location
     * 
     * @return Location
     */
    public function location()
    {
        return $this->morphOne('Location', 'locationable');
    }

    // ...

当我运行以下测试代码时,它会很好地创建位置条目,但如果我重复它,它会创建更多条目。

$person = Person::first();

$loc = new Location;

$loc->lat = "123";
$loc->lng = "321";

$person->location()->save($loc);

我在这里做错了吗?我本来希望morphOne 将其限制为每种类型一个条目,因此下表中的最后一个条目不应该存在:

+---------------------+--------------------------+
|  locationable_id    |   locationable_type      |
+---------------------+--------------------------+
|  2                  |  Building                |
|  3                  |  Building                |
|  2                  |  Person                  |
|  2                  |  Building                |
+---------------------+--------------------------+

【问题讨论】:

  • 不,你没有做错。这就是它的工作原理。多态关系适用于简单的事情,但越深入,发现的错误就越多。
  • 那么您是否建议尽可能避免使用它们?除了创建多态关系之外,我做任何其他事情都没有意义。 1) 有人建议做一个简单的 if else 检查orderable_type 是否为空然后创建,否则更新,您对此有何看法? 2) i.imgur.com/gPmh1OK.png 对此有何看法?很想听听。谢谢你。

标签: laravel laravel-4 eloquent polymorphism


【解决方案1】:

也许我迟到了,但这对我有用!

# Do we have location already?
if($person->location) {
    return $person->location()->update($location);
}
return $person->location()->create($location);

【讨论】:

  • 我通常把它放在模型上的一个方法中:saveLocation(Location $location){ ... } 一个漂亮又简单的api
【解决方案2】:

其实是通过调用

$loc = new Location;

根据定义,您正在创建一个新位置!

打电话

$person->location()->save($loc);

也无济于事。

如果您想更新一个位置,您需要找到该位置,更新它的值,然后保存它。独立于父模型:

$person = Person::first();

$loc = $person->location;

$loc->lat = "123";
$loc->lng = "321";

$loc->save();

完成。

【讨论】:

    【解决方案3】:

    根据我目前的经验,这个解决方案应该是可行的

    用新的 Location 模型实例创建或替换旧的:

    $person = Person::first();
    
    $loc = new Location;
    
    $loc->lat = "123";
    $loc->lng = "321";
    
    $loc->save();
    $person->location()->associate($loc);
    $person->save();
    

    更新:

    $person = Person::first();
    
    $person->location->lat = "123";
    $person->location->lng = "321";
    
    $person->location->save();
    $person->save();
    

    我花了很多天来找出这个解决方案。希望他们能更好地正式记录它。

    【讨论】:

      【解决方案4】:

      在 hasOne 或 morphOne 相关模型上创建或更新事物的最佳方法是使用“updateOrCreate”函数。

      就我而言,客户可以有一个地址,因此我执行以下操作并为我工作

      $client->address()->updateOrCreate([], $addressData);
      

      同样的事情也可以应用于 hasOne 关系的情况,比如用户只能拥有一个个人资料,所以我执行以下操作。

      $user->profile()->updateOrCreate([], $data);
      

      User.php

      class User {
          /**
           * Get the user profile information associated with the user.
           */
          public function profile()
          {
              return $this->hasOne('App\UserProfile');
          }
      }
      

      Client.php

      class Client {
          /**
           * Get all of the client's addresses.
           */
          public function address()
          {
              return $this->morphOne('App\Address', 'addressadder');
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-17
        • 1970-01-01
        相关资源
        最近更新 更多