5

Every time I perform the following:

$user = new User;
$user->name = 'John';
$user->save();

I want a field called "modified" to be updated to NOW() in MySQL. I can't use Laravel's timestamps because I'm only using a single modified field. I could rely on MySQL to do this for me, but I was wondering if there was a way to accomplish this in my Laravel model? Perhaps using a mutator in some way to set this before saving?

As a bonus: how would I do something like this $user->modified = "NOW()"? (which is obviously wrong, but hopefully demonstrates the point)

prograhammer
  • 20,132
  • 13
  • 91
  • 118
  • 1
    I guess you could `SELECT NOW()` and assign that. – Marty Jan 27 '15 at 01:35
  • 1
    yeah but that's an extra query – prograhammer Jan 27 '15 at 01:37
  • 2
    Yes, it is an extra query. You could use PHP's `time()` if the timezone etc is set the same as the MySQL install. – Marty Jan 27 '15 at 01:39
  • Yep!, @Marty thought of that too, but still defeats my goal for the question. Need a way to plug those MySQL constants/functions like `NOW()` in there. – prograhammer Jan 27 '15 at 01:40
  • @Prix I'm only using one column. So I have `public $timestamps = false;` in my models. – prograhammer Jan 27 '15 at 01:41
  • By default is updates 2 fields (one for create date, one for modified date). I only keep one field in my tables. – prograhammer Jan 27 '15 at 01:43
  • But this question could further provide a solution as to how we can get non-parameterized / non-quoted values (like NOW) into the query (without using a db::raw call) – prograhammer Jan 27 '15 at 01:45
  • You can't get values from the database without querying it, PHP doesn't provide a layer of methods that magically give you values that MySQL is meant to provide. – Marty Jan 27 '15 at 01:46
  • @Prix that will pass the string "NOW()" and not the MySQL NOW() function. @Marty I'm not sure what you are saying? In a simple PDO query we can say `users.modified = NOW()`, this is all I'm trying to do via setting a property or adding some code to do this in a method in the model somewhere. – prograhammer Jan 27 '15 at 01:48
  • Note that you said a simple PDO *query*. A query is involved here, which is the case for getting the value of `NOW()` as well. – Marty Jan 27 '15 at 01:49
  • Well, I'd love to quote you @Marty as I've been saying to so many folks how I think ORMs just don't work for complex projects. But nonetheless, attempting to avoid a raw query here. – prograhammer Jan 27 '15 at 01:51
  • @Prix I don't really want to keep fields in the database that aren't being used. Simple as that. Keeping all the growing data in memory is very important for fast querying. – prograhammer Jan 27 '15 at 01:53

1 Answers1

11

You can accomplish this in the saving event, for which you can register a callback in you model's boot method:

class User extends Eloquent {

    public static function boot()
    {
        static::saving(function($user)
        {
            $user->modified = DB::raw('NOW()');

            // Alternatively, you can use this:
            $user->modified = Carbon\Carbon::now();
        });

        parent::boot();
    }

}
Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • 1
    Hooray! Also solves a problem of where I wanted to add the session'd user to a `modified_by` field! `$user->modified_by = Auth::user()->id;` – prograhammer Jan 27 '15 at 01:59
  • @DavidGraham Doesn't this answer conflict with your comment: `But this question could further provide a solution as to how we can get non-parameterized / non-quoted values (like NOW) into the query (without using a db::raw call)`? – Marty Jan 27 '15 at 02:02
  • *could* (see bonus in question) – prograhammer Jan 27 '15 at 02:03
  • but also notice the use of `db::raw` here is not for running a raw query – prograhammer Jan 27 '15 at 02:05
  • Checked it! It works! `$user->modified = DB::raw("NOW()");` works. But I do see how my comment could be confusing @Marty I was referring to a full raw query `DB::select(DB::raw...` query – prograhammer Jan 27 '15 at 02:09
  • @DavidGraham I assumed `::raw` ran straight SQL on-demand (e.g. returned the value of `NOW()` in this instance). I am not familiar enough with Laravel to know whether that's the case or not. – Marty Jan 27 '15 at 02:11
  • No prob Marty, I +1 you. You are like me in that you don't just read a question mechanically, but think about it organically (in trying to see if there is a solution that still accomplishes the potential goal) – prograhammer Jan 27 '15 at 02:13
  • @DavidGraham - If you don't want to use `DB::raw`, just set it to a date object: `$user->modified = Carbon\Carbon::now()` – Joseph Silber Jan 27 '15 at 02:16
  • No I was just trying to avoid a raw query. Simply using the DB::raw is not an issue actually I realized. – prograhammer Jan 27 '15 at 02:17