'Laravel update hasMany relationship using saveMany
As the title suggests, i'm trying to update a hasMany() relationship. I have a Contacts
and a ContactsProperties
model in my application.
Contacts can have many properties associated with them.
My models are setup like so:
Contacts
Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Contacts extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'contacts';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'contact_name', 'first_name', 'last_name', 'email', 'telephone', 'created_at', 'updated_at'
];
/**
* Get properties associated with contact
*/
public function properties()
{
return $this->hasMany(ContactsProperties::class, 'contact_id');
}
}
ContactsProperties
Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ContactsProperties extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'contacts_properties';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'property_type', 'contact_id', 'address_line_1', 'address_line_2', 'city', 'county', 'postcode'
];
/**
* Get the contact that is assigned to the properties
*/
public function properties()
{
return $this->belongsTo(Contacts::class);
}
}
I can create new properties for a contact by doing:
$contact->properties()->createMany($request->address);
Which works perfectly.
My problem is when I want to update the properties, when editing the contact. I have tried this:
$contact = Contacts::find($request->id);
// Update properties
$contact->properties()->saveMany($request->address);
Which gives the following error:
Type error: Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model, array given, called in /var/www/MyApp/2016/public/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php on line 237
The value of $request->address is an array:
Array
(
[0] => Array
(
[address_line_1] => test
[address_line_2] => Lane
[city] => Test
[county] => test
[postcode] => test
[property_type] => site
)
)
Does anyone know how to achieve what I am trying to do?
Thank you in advance.
Solution 1:[1]
As error says it expects model instance, not an array. Try to create a ContactsProperties
instance from that request input, then you able to save it, f.e.
$contactProperties = new ContactProperties($request->address);
$contact->properties()->saveMany($contactProperties);
Solution 2:[2]
The saveMany()
methods takes a collection of models as the parameter (see the documentation). You cannot pass it an associative array. The error you received in from the save()
method, which is called once for each model in the collection, and expects a Model
as the parameter.
The saveMany()
method will insert new rows for new models and update rows for existing models.
It seems that that you are saving one ContactProperties
model at a time, in which case you could call the save()
method directly, instead of saveMany()
, but you need to pass it a ContactProperties
model, not the associative array from the request.
$contactProperties = new ContactProperties($request->address);
$contact->properties()->save($contactProperties);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | devnull ? |
Solution 2 | GeeC |