gpmcadam
gpmcadam

Reputation: 6550

Updating a One-To-Many Relationship in Laravel's Eloquent

Suppose I have a relationship between the following two Models in Laravel's Eloquent:

<?php

    // user:
    // - user_id
    class User extends Model
    {
        protected $table = 'users';

        public function settings()
        {
            return $this->hasMany('Setting');
        }

        public function settingSet($key, $value)
        {
            \Setting::setConfigItem($key, $value, $this->user_id);
        }

    }

    // settting:
    // - setting_key
    // - setting_value
    // - user_id
    class Setting extends Model
    {
        public function setConfigItem($key, $value, $user_id)
        {
            // Note: I've provided this code here as an example, so it should
            // exist here only as pseudo-code - it has not been tested and
            // is outside the scope of this issue but has been requested by 
            // a commenter so I've provided the basis for this method:
            $existing = \Setting::where(['key' => $key, 'user_id' => $user_id])->first();
            if (!$existing) {
                \Setting::insert([ 'setting_key' => $key, 'setting_value' => $value, 'user_id' => $user_id ]);
            } else {
                $existing->setting_value = $value;
                $existing->save();
            }
        }
    }

And I want to retrieve a single user and his settings, I can do the following:

<?php
$user = User::with(['setting'])->find(1);

Now, with this user, I can update or insert a setting using the settingSet method, as listed above.

<?php
$user->settingSet('foo','bar');

However, if I retrieve the settings at this point, I will get stale data.

<?php
print_r($user->settings); // onoes!

What's the best practice to force the data for this relationship to be updated after an INSERT/UPDATE/DELETE in the User::settingSet method or in other similar methods?

Upvotes: 7

Views: 2277

Answers (2)

mininoz
mininoz

Reputation: 5958

You can force the data to be updated by using Lazy Eager Loading, load() function.

print_r($user->load('settings'));

source: http://laravel.com/docs/5.0/eloquent#eager-loading

Upvotes: 1

Gal Sisso
Gal Sisso

Reputation: 1959

You have this issue due to using query builder instead of the eloquent,I dont understand why your using both,if you're using eloquent then use eloquent if you're using query builder use query builder,but dont use both,at least not when you have the possibility not to.

I find the setConfigItem method useless as you arent pushing a user into a setting but a setting into a user so basically all implementions should be on a user class and not on the settings class

After clearing that out,you could try doing something like this -

public function settingSet($key, $value)
{
    $setting = new Setting([
        'setting_key' => $key,
        'setting_value' => $value
    ]);
    $this->settings()->save($setting);
}

also you could improve this method by instead of accepting just 1 setting at a time you could accept array of settings

btw is there a reason why you arent using pivot table ? are the settings unique foreach user ?

Upvotes: 1

Related Questions