如何在 Laravel 5.1 中更新 hasMany 关系

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31023656/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:49:57  来源:igfitidea点击:

How to update hasMany relationship in Laravel 5.1

phplaravellaravel-5

提问by Merianos Nikos

I am totally new on Laravel, and I have implement the Usertable provided by Laravel Auth, and also I have create a table for the user meta data that is a Key Value pare table.

我完全是新的Laravel,我有落实User提供表格Laravel Auth,并且还我创建一个表是一个用户元数据Key Value pare table

The user meta table is created by the following code :

用户元表由以下代码创建:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class UserMeta extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('user_meta', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->char('meta_key', 255);
            $table->longText('meta_value')->nullable();
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('user_meta');
    }
}

In my User modelI have the following method:

在我的User model我有以下方法:

public function meta() {
    return $this->hasMany('App\Models\UserMeta');
}

and inside my UserMeta modelI have the following method:

在我的内部,我UserMeta model有以下方法:

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

Until now anything is fine. So, when I register a new user I perform the following actions:

直到现在一切都很好。因此,当我注册新用户时,我会执行以下操作:

$user = User::create(
    [
        'name'     => $data['name'],
        'email'    => $data['email'],
        'password' => bcrypt( $data['password'] ),
    ]
);

if ( $user ) {

    $telephone_number = new UserMeta;
    $telephone_number->user()->associate($user);
    $telephone_number->meta_key = 'telephone_number';
    $telephone_number->meta_value = $data['telephone_number'];
    $telephone_number->save();

    $company = new UserMeta;
    $company->user()->associate($user);
    $company->meta_key = 'company';
    $company->meta_value = $data['company'];
    $company->save();

    $web_site = new UserMeta;
    $web_site->user()->associate($user);
    $web_site->meta_key = 'web_site';
    $web_site->meta_value = $data['web_site'];
    $web_site->save();

}

return $user;

I suppose that should be a better way to perform that same actions, but I don't know what is the other way :( :)

我想这应该是执行相同操作的更好方法,但我不知道其他方法是什么:(:)

So, the above code works very nice for me, but now the problem is with the value update. In this case, how can I update the Meta Datawhen I update the user profile ?

所以,上面的代码对我来说非常好,但现在问题出在值更新上。在这种情况下,如何Meta Data更新用户配置文件?

In my updatemethod of my UserControler, I perform the following actions:

在 my 的update方法中UserControler,我执行以下操作:

$user = User::where( 'id', '=', $id )->first();

$user = User::where('id', '=', $id )->first();

$user->name  = $request->input( 'name' );
$user->email = $request->input( 'email' );
$user->password = bcrypt( $request->input( 'password' ) );

$user->save();

My $request->input();has the following extra fields that corresponding to meta values telephone_number, web_site, company.

$request->input();有一个对应的元值以下额外字段telephone_numberweb_sitecompany

So, how can I update the meta values in the user_meta table ?

那么,如何更新 user_meta 表中的元值?

采纳答案by stef

Looping through values

循环遍历值

Firstly, you are right that you could loop through the three keys in your create method to:

首先,您可以循环遍历 create 方法中的三个键是对的:

// Loop through all the meta keys we're looking for
foreach(['telephone_number', 'web_site', 'company'] as $metaKey) {
    $meta = new UserMeta;
    $meta->meta_key = $metaKey;
    $meta->meta_value = array_get($data, $metaKey);
    $meta->save();
}

The Update Method: Approach One

更新方法:方法一

Then, in your update method

然后,在您的更新方法中

// Loop through all the meta keys we're looking for
foreach(['telephone_number', 'web_site', 'company'] as $metaKey) {
    // Query for the meta model for the user and key
    $meta = $user->meta()->where('meta_key', $metaKey)->firstOrFail();
    $meta->meta_value = array_get($data, $metaKey);
    $meta->save();
}

Note the firstOrFail()to end the query. This is just me being strict. If you wanted to add a meta value if it didn't exist, then you could replace that line with

注意firstOrFail()结束查询。这只是我严格。如果您想添加不存在的元值,则可以将该行替换为

// Query for the meta model for the user and key, or
// create a new one with that key
$meta = $user->meta()->where('meta_key', $metaKey)
    ->first() ?: new UserMeta(['meta_key' => $metaKey]);

The Update Method: Approach Two

更新方法:方法二

This approach is a little more efficient, but a more complex (but also potentially teaches about a cool feature of Eloquent!).

这种方法效率更高一些,但也更复杂(但也可能教导 Eloquent 的一个很酷的特性!)。

You could load in all of the meta keys first (see lazy eager loading).

您可以先加载所有元键(请参阅延迟预加载)。

// load the meta relationship
$user->load('meta');

// Loop through all the meta keys we're looking for
foreach(['telephone_number', 'web_site', 'company'] as $metaKey) {
    // Get the first item with a matching key from the loaded relationship
    // Or, create a new meta for this key
    $meta = $user->meta
        ->first(function($item) use ($metaKey) { 
            return $item->meta_key === $metaKey; 
        }) ?: new UserMeta(['meta_key' => $metaKey]);
    $meta->meta_value = array_get($data, $metaKey);
    $meta->save();
}