Kousha
Kousha

Reputation: 36189

Laravel Eloquent - Set column inside Model

I have a "tickets" table for create bug-report system. This ticket has an enum status column that is either open, close, or solved.

Instead of opening/closing/solving the ticket inside the controller, I just want to do it within the model; i.e. I want to have functions called open(), close(), and solved() so that I can just go Ticket::find($id)->close();. This should set the attribute status to close and then SAVE it!

What's the best approach for this? Also, would this be considered bad practice? Should I do this within the controller?

I tried doing this, but did not succeeded:

public function close()
{
   $this->status = 'close';
   // Also tried $this->attributes['status'] = 'close';
   $this->save();
}

Upvotes: 2

Views: 4706

Answers (3)

Pathros
Pathros

Reputation: 10720

Another way is to use update() function, but before doing that, you've got to make sure that the columns to update are indeed inside the $fillable array.

//make sure in fillable
protected $fillable = [
   'status',
];

// ...

// In your model
public function close()
{
    $this->update([
       $this->status = 'close'; 
    ]);
}

Cheers.

Upvotes: 1

The Alpha
The Alpha

Reputation: 146191

In my opinion this is the better way than doing it directly from controller and you may use scopeMethod for this, for example:

function scopeClose($query)
{
    // Close the ticket and return $query;
    return $query->where('...');
}

If you return the $query then you may do method chaining. For example:

Ticket::find($id)->close()->otherMethodCall();

If you execute the query for example, $query->update('...') then returning the $query won't make any sense because it'll be the result of update method and which is true/false.

The benefit to use the scope method is:

// In your model
function scopeClose($query, $id)
{
    $model = $query->find($id);
    $model->status = 'whatever';
    $model->save();
    return true; // Or just return $model->save();
}

So you may use in your controller:

Ticket::close(10); // Update the status of record with id 10

Upvotes: 2

ceejayoz
ceejayoz

Reputation: 179994

That's a perfect thing to put in a model, IMO.

class Ticket extends Eloquent {
  public function open() {
    $this->status = 'open';
    $this->save();
  }
}

Upvotes: 6

Related Questions