Can't get Laravel associate to work
Asked Answered
S

3

28

I'm not quite sure if I understand the associate method in Laravel. I understand the idea, but I can't seem to get it to work.

With this (distilled) code:

class User
{

    public function customer()
    {
        return $this->hasOne('Customer');
    }

}

class Customer
{

    public function user()
    {
        return $this->belongsTo('User');
    }

}

$user = new User($data);
$customer = new Customer($customerData);

$user->customer()->associate($customer);

I get a Call to undefined method Illuminate\Database\Query\Builder::associate() when I try to run this.

From what I can read, I do it exactly as is stated in the docs.

What am I doing wrong?

Saving answered 2/10, 2014 at 12:19 Comment(0)
V
53

I have to admit that when I first started using Laravel the relationships where the part that I had to consistently refer back to the docs for and even then in some cases I didn't quite get it right.

To help you along, associate() is used to update a belongsTo() relationship. Looking at your code, the returned class from $user->customer() is a hasOne relationship class and will not have the associate method on it.

If you were to do it the other way round.

$user = new User($data);
$customer = new Customer($customerData);

$customer->user()->associate($user);
$customer->save();

It would work as $customer->user() is a belongsTo relationship.

To do this the other way round you would first save the user model and then save the customer model to it like:

$user = new User($data);
$user->save();

$customer = new Customer($customerData);
$user->customer()->save($customer);

Edit: It may not be necessary to save the user model first but I've just always done that, not sure why.

Vernon answered 2/10, 2014 at 12:32 Comment(4)
Yes, your first thing seems to work correctly. I think it's kinda odd that it has to work that way around. Anyhoe, thanks. And so that you may learn something new: $user->push(); saves the user and all it's relationships.Saving
I noticed that we need to do $customer->save() after ->associate($something)Ardeth
in other words, User class hosts/has the Customer. So that we can associate/disassociate the user to/off a given customer like $customer->user()->associate($user) or $customer->user()->associate(), next to $customer->save()Minim
You can also directly save after the association like this $customer->user()->associate($user)->save();Photogenic
M
10

As I understand it, ->associate() can onyl be called on a BelongsTo relationship. So, in your example, you could do $customer->user()->associate($user). However, in order to 'associate' a Has* relationship you use ->save(), so your code should be $user->customer()->save($customer)

Matterhorn answered 2/10, 2014 at 12:32 Comment(4)
having same problem. but on belongToMany() relation. how could I fix this? thanksUnlikely
For many-to-many methods (see docs laravel.com/docs/5.3/…) you use ->attach() and ->detach(). E.g. $post->tags()->attach($tag); Now, officially, the attach and detach method only accept IDs, but when I tested this some time ago on 4.x, you could pass actual models in. That may have changed for 5.x.Matterhorn
this kinda working. but its asking for an array, and i'm getting object instead.Unlikely
I think your best course of action here is to ask a new question specific to your problem. Include the version of Laravel you are using and any relevant code and I'm sure you will get the help you need.Matterhorn
L
0

just add ->save() to the end.

$user->customer()->associate($customer)->save();

Liquidate answered 16/12, 2022 at 6:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.