Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

isaackearl's avatar

Proper way to make a custom function for my Model?

I'm having a hard time wrapping my head around eloquance and could use a little help doing a task that I'm sure is fairly common.

I have a table called Vacations that has a 1 to many relationship with another table called Employees. The information stored in the vacation table is an instance of a vacation they went on (some data pertaining to the vacation).

Only one of the entries in the vacation table should be "active" for a particular employee at a given time. To accomplish this I added a field "is_active" to the vacation table, and I wanted to make a function on the Vacation model, that allows me to setAsActive(). This would then find all the vacation objects for the employee, set them to is_active=0, then change the is_active field to 1 for the object I called the function on. like this:

//inside my Vacation model

 public function setAsActive()
 {
        foreach($this->employee->vacations()->where('id','!=', $this->id)->get() as $vac)
        {
            $vac->is_active = 0;
            $vac->save();
        }

        $this->is_active = 1;
        if($this->save()) {
            return true;
        }
        return false;
 }

I'm trying to use it like this:

$employee = Employee::find(100);
$employee->vacations[0]->setAsActive();
// true

If I check the database I can see that it actually worked. If I then get a new employee object then everything is fine... However I am trying to understand how I can continue using the same $employee object that I originally had. After I setAsActive() as I do above, and then try and inspect my employee object I see that it still has all the vacation objects but only the one that got updated to is_active = 1 has been updated in the instance of the model.

$employee->vacations->toArray();

I'll get something that shows 2 vacations (as expected) but they'll both be is_active = 1.. so my function doesn't properly update the model I'm using. Any help would be appreciated. I am probably just using models wrong and I need to shift my way of thinking. I'm trying really hard to learn laravel and step into modern times but I've been developing with old tools and ideas for awhile now.

Thanks

EDIT* I'm still trying different things and still not having alot of luck. After further inspection my code above I don't think even worked as I said it does. because I just looked in the database and both my vacation entries in the database for this employee were set to 1. I also want to point out that other then creating my own functions I'm not having as much trouble with models. All my relationships work as I expect so far. If someone could point me in the right direction for writing my own functions like this one that would be awesome.

0 likes
6 replies
austenc's avatar

Could you just find the vacation by its id, then do the employee find afterward? Something like:

$v = Vacation::find($vacationId);
$v->setAsActive();
$employee = Employee::find($personId);
alsofronie's avatar
Level 7

Maybe you can put that code directly into your setter method?

public function setIsActiveAttribute($value)
{
    if($value) {
        // avoid multiple queries and avoid iterating through them
        $idEmp = $this->attributes['employee_id'];
        $idVac = $this->attributes['id'];
        static::where('employee_id','=',$idEmp)->where('id','<>',$idVac)->update(['is_active'=>0]);
    }
    $this->attributes['is_active'] = $value;
 }

Of course, you can put everything in one line of code after testing the value to be active. This way, you can transparently set the attribute in your controller and use the save method as it should be. It makes your controller code much cleaner:

$vacantion->is_active = 1;
$vacantion->save();
2 likes
thepsion5's avatar

After you save the current model, try adding this line:

$this->employee->load('vacations');

That should reload the entire collection from the database.

You can also reduce the number of SQL queries by using this instead:

$this->employee->vacations()->where('id','!=', $this->id)->where('is_active', 1)->update('is_active', 0);

So your function would end up like this:

function activate()
{
    $this->employee->vacations()->where('id','!=', $this->id)->where('is_active', 1)->update('is_active', 0);
    $this->is_active = 1;
    return $this->save();
}

Are you using some kind of model-based validation to that might prevent the previously-active vacation from being saved?

1 like
isaackearl's avatar

Testing these things! thanks for the responses guys I'll get right back to you and let you know how it goes.

isaackearl's avatar

Wow thanks both of you so much! The knowledge that I was missing that I needed to understand was being able to make setter methods etc using setIsActiveAttribute. I also am able to use $employee->load('vacations'); after I save the model in order to have a properly updated model to continue using.

In other words.. I didn't know how to use mutators and Accessors.

Thanks!

watkinsayden81's avatar

Struggling with academic writing? AllEssayWriter is here to help with top-notch custom essay services tailored to your needs. Our team of experienced writers ensures each essay is unique, thoroughly researched, and professionally written. Whether you're facing tight deadlines or complex topics, AllEssayWriter guarantees quality and originality, helping you achieve academic success effortlessly. Trust AllEssayWriter for a custom essay experience that stands out!

Please or to participate in this conversation.