【问题标题】:Updateorcreate always create | How to use it?更新或创建总是创建 |如何使用它?
【发布时间】:2019-08-03 15:14:24
【问题描述】:

我尝试在观察者中使用 updateOrCreate 函数。 所以我有这个功能:

 $transportpropremoyenaller = Transport::updateOrCreate(
        ['centre_id' => $gestionsejour->centre_id, 'allerouretour' => 
'Aller', 'date' => $gestionsejour->datedebut],
        ['ville' =>  \Config::get('constants.transport.0'), 'tarif' => '0']
    );

我在 GestionsejourObserver 中使用这个功能:

 public function created(Gestionsejour $gestionsejour)
{
    return $this->addtransportpropremoyen($gestionsejour);
}

当我创建一个新对象时,updateOrCreate 从不更新,总是创建一个新对象。

Gestionsejour 模型是:

 protected $fillable = [
    'datefin',
    'user_id',
    'agrement',
    'centre_id',
    'datedebut',
    'created_at',
    'updated_at',
    'deleted_at',
    'dureesejour',
    'periodesejour',
    'complet',
];

public function centre()
{
    return $this->belongsTo(Centre::class, 'centre_id');
}

public function getDatedebutAttribute($value)
{
    return $value ? Carbon::parse($value)->format(config('panel.date_format')) : null;
}

public function setDatedebutAttribute($value)
{
    $this->attributes['datedebut'] = $value ? Carbon::createFromFormat(config('panel.date_format'), $value)->format('Y-m-d') : null;
}

public function getDatefinAttribute($value)
{
    return $value ? Carbon::parse($value)->format(config('panel.date_format')) : null;
}

public function setDatefinAttribute($value)
{
    $this->attributes['datefin'] = $value ? Carbon::createFromFormat(config('panel.date_format'), $value)->format('Y-m-d') : null;
}

public function user()
{
    return $this->belongsTo(User::class, 'user_id');
}

Myabe 无法发送 3 个属性或日期有问题。我不知道。我正在阅读 laravel 文档,但不明白这个简单函数有什么问题。

【问题讨论】:

  • 在您的数据库中检查 datedebut,恕我直言,我认为即使在同一年、同一月和同一天,它们在时间部分也是不同的。如果是这样,更新部分不会一直找到相等的值。
  • 数据库中的日期是日期格式,因此它们不是时间部分。只是 Mont 、 day 和 years。

标签: laravel laravel-5 eloquent


【解决方案1】:

我认为你的问题在于这种方法getDatedebutAttribute 当您运行以下代码时,还会使用访问器,这意味着您正在搜索 d-m-y 格式,如下所示。

'date' => $gestionsejour->datedebut // '03-08-2019' <- because of getDatedebutAttribute

也许您可以创建一个辅助方法,而不是使用访问器和修改器。让模型上的数据与数据库中的数据相同。 您可以在模型上做的另一件事是用 $dates 告诉哪些列是日期,因此它们将自动成为碳对象

// Model.php

/**
 * The attributes that should be mutated to dates.
 *
 * @var array
 */
protected $dates = [
    'datedebut',
];


public function formattedDateDebut()
{
    return $this->datedebut ? $this->datedebut->format('d-m-y') : null;
}

并像这样在您的视图中使用它。

{{ $gestionsejour->formattedDateDebut() }}

这样你也不再需要setDatedebutAttribute了,因为Y-m-d是你在这里使用时的默认格式'date' =&gt; $gestionsejour-&gt;datedebut

【讨论】:

  • 就是这样。日期有问题。我只是将日期转换为绕过访问器并将其发送到我的函数中的 Y-m-d 格式,现在可以了。它更简单,因为许多模板在我的项目中使用访问器日期。谢谢
【解决方案2】:

更好:你可以考虑这样的事情。


    public function setTypeAttribute($value) {
        $typeVal = array_search($value, self::TYPE);
        if ($typeVal === false)
            $typeVal = $value;
        $this->attributes['type'] = $value;
    }

您将需要绕过突变,因为这是 updateOrCreate 幕后发生的事情:

    public static function updateOrCreate($where, $fields) {
        $record = self::where($where)->first();
        if ($record) {
            $record->update($fields);
        }
        else
            $record = self::create(array_merge($where, $fields));
        return $record;
    }

请注意,对于 $where,不应该有突变,但对于 $fields,它会在访问数据库之前发生突变,当您合并 $where 和 $fields 时会出现问题,您将未突变的值混合到$字段。

或解决方案 2,将预变异值附加到 updateOrCreate() 的第二个参数。例如。

updateOrCreate(['date' => $mutatedValue], [
  'date' => $premutatedValue
])

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多