limit
limit

Reputation: 647

Laravel Update Related Model with push?

I am stuck on updating a eagerloaded model that has a "hasMany" relation.

I have one model like so:

class UserGroup extends Model
{

  public function enhancements()
  {
    return $this->hasMany('App\UserGroupEnhancement');
  }

}

My controller is passing $userGroup to the view like so:

$userGroup = $this->userGroup->with('enhancements')->whereId($id)->first();

and then in my view I have

  @foreach($userGroup->enhancements as $enhancement)

  <label>{{$enhancement->type}}</label>
  <input class="form-control" name="enhancements[{{$enhancement->id}}][price]" value="{{$enhancement->price}}">

  @endforeach

When updating, how do I update all of records in the enhancement relationship? It's passed back into multiple arrays. I am currently doing something like this.

public function update($id)
{
    $userGroup = $this->userGroup->findOrFail($id);
    $enhancement = \Input::get('enhancements');
    if (is_array($enhancement)) {
        foreach ($enhancement as $enhancements_id => $enhancements_price) {
            $userGroup->enhancements()->whereId($enhancements_id)->update($enhancements_price);
        }
     }
 }

Is there a way I can do this without needing the foreach loop? I see the push() method, but seems to only work on a single array.

Upvotes: 2

Views: 516

Answers (1)

dynamic
dynamic

Reputation: 48091

There isn't a better way to do this. There is an Eloquent method called saveMany but it is used to create new records and not update. ExampleDoc:

$comments = [
    new Comment(['message' => 'A new comment.']),
    new Comment(['message' => 'Another comment.']),
    new Comment(['message' => 'The latest comment.'])
];

$post = Post::find(1);

$post->comments()->saveMany($comments);

I would stick with your solution, you can even create a trait or a base Eloquent class and put that logic in a method so it can be used by all other models, if you ever need to. Something like:

trait UpdateMany {

    public function updateMany($updates, $relationshipName)
    {

        if (!empty($updates)) {
            foreach ($updates as $update_id => $update) {
                $this->{$relationshipName}()->whereId($update_id)->update($update);
            }
       }

    }
}

Then attach to your model(s):

class UserGroup extends Model
{

    use UpdateMany;

    public function enhancements()
      {
        return $this->hasMany('App\UserGroupEnhancement');
      }

}

And simply use as:

$userGroup = $this->userGroup->findOrFail($id);
$userGroup->updateMany(\Input::get('enhancements'), 'enhancements');

Upvotes: 1

Related Questions