简体   繁体   中英

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?

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 ?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM