Laravel - Eloquent覆盖自定义时间戳...为什么?

时间:2016-03-11 17:15:14

标签: mysql laravel eloquent

我正在制作库存管理系统。 当产品缺货时,我在表格中输入并注意" oos_at"带有日期/时间的字段。

之后,当它重新有货时,我会找到该条目并更新" restocked_at"时间戳字段。

然而,当我做第二个动作时,我的" oos_at"字段被查询的时间戳(' updated_at')字段覆盖... 我必须跟踪这个" oos_at"另一个实体上的字段,因此它不会被覆盖,然后使用该字段更新" oos_at"第二次更新该表时...

以下是我的代码......

class Pusher extends Model {
/**
 *
 *
 * @param Carbon $oos_at
 * @return bool
 */
public function setAsOutOfStock(Carbon $oos_at)
{
    Log::info([
        'FILE'  => get_class($this),
        'method'   => 'setAsOutOfStock',
        'pusher'    => $this->id,
        'param:oos_at'  => $oos_at->toDateTimeString(),
    ]);

    $this->pusherOutOfStocks()->create([
        'location_id'   => $this->location_id,
        'product_id'    => $this->product_id,
        'oos_at'        => $oos_at->toDateTimeString(),
    ]);

    $this->oos = true;
    $this->oos_at = $oos_at;
    return $this->save();
}

/**
 * Clear the PusherOutOfStocks attached to $this Pusher
 * (This Pusher has been restocked!)
 *
 * @param Carbon $time
 * @return bool
 */
public function setAsInStock(Carbon $time)
{
    Log::info([
        'FILE'      => get_class($this),
        'method'    => 'setAsInStock',
        'pusher'    => $this->id,
        'param:time' => $time->toDateTimeString(),
    ]);

    $this->pusherOutOfStocks()->where('restocked_at', null)
        ->update(['restocked_at' => $time->toDateTimeString()]);

    $this->oos = false;
    $this->oos_at = null;
    return $this->save();
}
}

当我在推进器重新进货之前死亡并倾倒PusherOutOfStocks时,那么" oos_at"设置得当。

Illuminate\Database\Eloquent\Collection {#340
  #items: array:1 [
    0 => Newave\Engineering\PusherOutOfStock {#343
      #fillable: array:5 [
        0 => "pusher_id"
        1 => "location_id"
        2 => "product_id"
        3 => "oos_at"
        4 => "restocked_at"
      ]
      #dates: array:2 [
        0 => "oos_at"
        1 => "restocked_at"
      ]
      #connection: null
      #table: null
      #primaryKey: "id"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:9 [
        "id" => 246
        "pusher_id" => 216
        "location_id" => 634
        "product_id" => 378
        "oos_at" => "2016-03-11 03:00:00"
        "restocked_at" => null
        "created_at" => "2016-03-11 12:12:01"
        "updated_at" => "2016-03-11 12:12:01"
        "deleted_at" => null
      ]
      #original: array:9 [
        "id" => 246
        "pusher_id" => 216
        "location_id" => 634
        "product_id" => 378
        "oos_at" => "2016-03-11 03:00:00"
        "restocked_at" => null
        "created_at" => "2016-03-11 12:12:01"
        "updated_at" => "2016-03-11 12:12:01"
        "deleted_at" => null
      ]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #guarded: array:1 [
        0 => "*"
      ]
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
  ]
}

当我在推进器重新进货后死亡并倾倒PusherOutOfStocks时," oos_at"与" updated_at"

相同
Illuminate\Database\Eloquent\Collection {#408
  #items: array:1 [
    0 => Newave\Engineering\PusherOutOfStock {#775
      #fillable: array:5 [
        0 => "pusher_id"
        1 => "location_id"
        2 => "product_id"
        3 => "oos_at"
        4 => "restocked_at"
      ]
      #dates: array:2 [
        0 => "oos_at"
        1 => "restocked_at"
      ]
      #connection: null
      #table: null
      #primaryKey: "id"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:9 [
        "id" => 244
        "pusher_id" => 214
        "location_id" => 626
        "product_id" => 374
        "oos_at" => "2016-03-11 12:10:23"
        "restocked_at" => "2016-03-11 04:00:00"
        "created_at" => "2016-03-11 12:10:22"
        "updated_at" => "2016-03-11 12:10:23"
        "deleted_at" => null
      ]
      #original: array:9 [
        "id" => 244
        "pusher_id" => 214
        "location_id" => 626
        "product_id" => 374
        "oos_at" => "2016-03-11 12:10:23"
        "restocked_at" => "2016-03-11 04:00:00"
        "created_at" => "2016-03-11 12:10:22"
        "updated_at" => "2016-03-11 12:10:23"
        "deleted_at" => null
      ]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #guarded: array:1 [
        0 => "*"
      ]
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
  ]
}

我甚至使用过DB :: getQueryLog()并看到NOWHERE' oos_at'正在明确设置/更新......

我的代码中没有其他地方修改过此表...

有谁知道这里发生了什么???? 谢谢!!

=============

额外代码片段

表格迁移::

    Schema::create('pusher_out_of_stocks', function (Blueprint $table) {
        $table->increments('id');

        $table->integer('pusher_id');
        $table->integer('location_id');
        $table->integer('product_id');

        $table->timestamp('oos_at');
        $table->timestamp('restocked_at')->nullable();

        $table->timestamps();
        $table->softDeletes();
    });

PusherOutOfStock类

class PusherOutOfStock extends Model
{
    use SoftDeletes;

    protected $fillable = [
        'pusher_id',
        'location_id',
        'product_id',
        'oos_at',
        'restocked_at',
    ];

    protected $dates = [
        'oos_at',
        'restocked_at'
    ];

    /**
     * A PusherOutOfStock belongsTo a Product
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function product()
    {
        return $this->belongsTo(Product::class);
    }

    /**
     * A PusherOutOfStock belongsTo a Pusher
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function pusher()
    {
        return $this->belongsTo(Pusher::class);
    }

    /**
     * A PusherOutOfStock belongsTo a Location
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function location()
    {
        return $this->belongsTo(Location::class);
    }
}

以下是代码用于命中该更新方法的序列

首先,它在我的API命名空间

中命中了我的InventoryController
    public function upload(Request $request)
    {
        $data = $request->all();

        $header = $this->getHeader($data);
        $body   = $this->getBody($data);

        $reader = $this->getReaderFromHeader($header);

        if ( ! $this->guardAgainstNoReader($reader))
            return (new Response("Reader with mac-address: ". $header['reader_mac'] . " does not exist.", 409));

        $result = $this->inventoryRepository->uploadPusherData($reader, $header, $body);

        return $result;
    }

然后它将请求发送到InventoryRepository

public function uploadPusherData(Reader $reader, $header, $body)
{
    foreach ($body as $pusherData)
    {
        $result[] = $this->processPusherData($pusher, $header['timestamp'], $pusherData);
    }
    return $result;
}

然后,在存储库中,它一次处理一行(在我的测试中,只有一行)

private function processPusherData(Pusher $pusher, $timestamp, $pusherData)
{
    $latestInventory = $pusher->latestInventory;

    if (! $latestInventory)
        return $this->updatePusher($pusher, $timestamp, $pusherData);

    if ($latestInventory->tags_blocked == $pusherData['data_TAGSBLKED'])
        return $this->noChangeRecorded($pusher, $latestInventory, $timestamp);

    return $this->updatePusher($pusher, $timestamp, $pusherData);
}

然后更新推送器......

public function updatePusher($pusher, $timestamp, $pusherData)
{
    // See if there are any existing already
    $prevInv = $pusher->latestInventory;

    // Create the new data
    $inventory = Inventory::create([
        'pusher_id'     => $pusher->id,
        'product_id'    => $pusher->product_id,
        'reader_id'     => $pusher->reader->id,
        'tags_blocked'  => $pusherData['data_TAGSBLKED'],
        'paddle_exposed'=> $pusherData['paddle_exposed'],
        'created_at'    => Carbon::createFromTimestamp($timestamp)
                            ->toDateTimeString(),
    ]);

    if (  !$prevInv || $prevInv->id == $inventory->id )
    {
        return "first-data" . $timestamp;
    }

    return $this->checkForEvents($inventory, $prevInv);
}

我们检查是否应该触发任何事件......在这种情况下,之前的库存中有9件库存...现在有0件。

private function checkForEvents(Inventory $currentInventory, Inventory $previousInventory)
{
    if ( ! $previousInventory->oos && $currentInventory->oos && $previousInventory->pusher->oos_notified == 0)
    {
        $currentInventory->pusher->oos_notified = true;
        $currentInventory->pusher->save();
        return Event::fire(new InventoryOutOfStock($currentInventory));

    }

    if ( ( $previousInventory->oos || $previousInventory->status == "RESTOCK" )
            && $currentInventory->tags_blocked > 2 )
    {
        return Event::fire(new PusherWasRestocked($currentInventory));
    }

    if ( $currentInventory->status == "RESTOCK" && $previousInventory->pusher->low_stock_notified == 0)
    {
        $currentInventory->pusher->low_stock_notified = true;
        $currentInventory->pusher->save();
        return Event::fire(new LowStockAlert($currentInventory));
    }

    return "no-events";
}

然后触发事件InventoryOutOfStock

触发3个事件...... 2与发送的通知等有关。

    'App\Events\InventoryOutOfStock' => [
        'App\Listeners\InventoryOutOfStockUpdater',
        'App\Listeners\EmailInventoryOutOfStockNotification',
        'App\Listeners\SMSInventoryOutOfStockNotification',

//' App \ Listeners \ OutOfStocksUpdater',         ],

这导致我们......

public function handle(InventoryOutOfStock $event)
{
    $pusher = $event->pusher;
    $inventory = $event->inventory;
    $product = $pusher->product;

    $oos = $pusher->setAsOutOfStock($inventory->created_at);

    $locationPushers = $product->getPushersByLocation($pusher->location);
    $isInStock = false;
    foreach ($locationPushers as $pusher)
        if ($pusher->oos == 0)
            $isInStock = true;

    if (! $isInStock)
        $product->productOutOfStocks()->create([
            'location_id'   => $pusher->location_id,
            'oos_at'        => $event->inventory->created_at,
        ]);
}

1 个答案:

答案 0 :(得分:2)

我认为您不必使用timestamp方法来创建字段,但您应该使用dateTime方法:

Schema::create('pusher_out_of_stocks', function (Blueprint $table) {
    $table->increments('id');

    $table->integer('pusher_id');
    $table->integer('location_id');
    $table->integer('product_id');

    $table->dateTime('oos_at');
    $table->dateTime('restocked_at')->nullable();

    $table->timestamps();
    $table->softDeletes();
});

这应该有效:)

希望它有所帮助!