Asked  9 Months ago    Answers:  5   Viewed   46 times

I found this answer on the subject, but it doesn't work for me.

So, I make an entry in the database:

// Write lead to database
$lead = Lead::create($lead_data);

And the timestamps look like this, which is good:

| 2016-01-08 10:34:15 | 2016-01-08 10:34:15 |

But then I make a request to an external server, and I need to update the row:

$lead->user_id = $response['user_id'];
$lead->broker_id = $response['broker_id'];
$lead->save();

and the created_at field gets changed:

| 2016-01-08 04:34:17 | 2016-01-08 10:34:17 |

How do I solve this problem?

EDIT

I need a solution that would just modify the behavior without dropping columns or resetting migrations. The fix has to be performed on a live database without touching the data. As suggested below, I tried the following migration:

$table->datetime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->change();

but nothing happens. The created_at field still gets modified on update.

 Answers

40

If you're on Laravel 5.2 and using MySQL, there was a bit of a "bug" introduced with the timestamps. You can read all about the issue on github here. It has to do with the timestamp defaults, and MySQL automatically assigning DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes under certain conditions.

Basically, you have three options.

  1. Update MySQL variable:

If you set the explicit_defaults_for_timestamp variable to TRUE, no timestamp column will be assigned the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes automatically. You can read more about the variable here.

  1. Use nullable timestamps:

Change $table->timestamps() to $table->nullableTimestamps(). By default, the $table->timestamps() command creates timestamp fields that are not nullable. By using $table->nullableTimestamps(), your timestamp fields will be nullable, and MySQL will not automatically assign the first one the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes.

  1. Define the timestamps yourself:

Instead of using $table->timestamps, use $table->timestamp('updated_at'); $table->timestamp('created_at'); yourself. Make sure your 'updated_at' field is the first timestamp in the table, so that it will be the one that is automatically assign the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes.

Wednesday, March 31, 2021
 
MassiveAttack
answered 9 Months ago
31

This can be done in (at least) 2 ways.

Using pure Eloquent model logic:

class Buy extends Model
{
  public function getTotalPrice() {
    return $this->buyDetails->sum(function($buyDetail) {
      return $buyDetail->quantity * $buyDetail->price;
    });
  }
}

The only issue here is that it needs to fetch all buy details from the database but this is something you need to fetch anyway to display details in the view.

If you wanted to avoid fetching the relation from the database you could build the query manually:

class Buy extends Model
{
  public function getTotalPrice() {
    return $this->buyDetails()->sum(DB::raw('quantity * price'));
  }
}
Saturday, May 29, 2021
 
Jeff
answered 7 Months ago
68

One simple solution.

In your Model

protected $rules = [
    'email_address' => 'sometimes|required|email|unique:users',
    ..
];

In your Controller, action:update

...
$rules = User::$rules;
$rules['email_address'] = $rules['email_address'] . ',id,' . $id;
$validationCertificate  = Validator::make($input, $rules); 
Monday, June 21, 2021
 
hillz
answered 6 Months ago
12

You would have to recursively get the children if you have an unknown depth like that.

Another option is to use the nested sets model instead of the adjacency list model. You can use something like baum/baum package for Laravel for nested sets.

"A nested set is a smart way to implement an ordered tree that allows for fast, non-recursive queries." - https://github.com/etrepat/baum

With this package you have methods like getDescendants to get all children and nested children and toHierarchy to get a complete tree hierarchy.

Wikipedia - Nested Set Model

Baum - Nested Set pattern for Laravel's Eloquent ORM

Managing Hierarchical Data in MySQL

Wednesday, June 23, 2021
 
Amber
answered 6 Months ago
61

Yes, it's your schema. The constraint on likes.post_id will prevent you from deleting records from the posts table.

One solution could be using onDelete('cascade') in the likes migration file:

Schema::create('likes', function (Blueprint $table) {
    $table->integer('post_id')->unsigned();
    $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
});

This way, when a post is deleted, all related likes will be deleted too.

Or, if you have a relationship from the Post model to the Like model, you can $post->likes()->delete() before deleting the post itself.

Wednesday, July 21, 2021
 
freeMagee
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share