laravel 在 Eloquent 中使用带有数据透视表字段的访问器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17196127/
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 07:59:56  来源:igfitidea点击:

Using accessors with pivot table fields in Eloquent

laravellaravel-4eloquent

提问by Euan T

I've currently got a few models that have many to many relationships via laravel. here's the structure:

我目前有一些模型通过 laravel 具有多对多的关系。这是结构:

users
    id
    username
    ...

games
    id
    title
    ...

game_user
    game_id
    user_id
    system

Now, my models look a little like this:

现在,我的模型看起来有点像这样:

<?php

class Game extends Eloquent
{
    /**
     * A game is owned by many users
     *
     * @return mixed
     */
    public function user()
    {
        return $this->belongsToMany('User')->withPivot('system');
    }


<?php

class User extends Eloquent
{
    /**
     * A user has many games.
     *
     * @return mixed
     */
    public function games()
    {
        return $this->belongsToMany('Game')->withPivot('system');
    }

Now, this all works fine. However, I wish to use a mutator upon the system field from the pivot table. I can't find any documentation on this and the following (in both the User and Game models) does not work:

现在,这一切正常。但是,我希望在数据透视表的系统字段上使用修改器。我找不到任何关于此的文档,以下(在用户和游戏模型中)不起作用:

public function getSystemAttribute($val)
{
    return $val.' Testing';
}

回答by Collin James

I haven't tested but this should work.

我还没有测试过,但这应该有效。

public function getSystemAttribute($value)
{
    return $this->pivot->system . ' Testing';
}

...

foreach ($user->games as $game)
{
    echo $game->system;
}

The value getting passed in is being pulled from the models attributes. There is no system attribute so you should get NULL. We can just ignore that and pull the value from the pivot table directly.

传入的值是从模型属性中提取的。没有系统属性,所以你应该得到 NULL。我们可以忽略它并直接从数据透视表中提取值。

回答by ira

You need to define an accessor for the pivot's systemproperty and add the attribute name to the appends property on the model. The whole procedure follows

您需要为枢轴的system属性定义一个访问器,并将属性名称添加到模型的 appends 属性中。整个流程如下

1) Define an accessor in the parent Model from where we want to access the attribute:

1)在父模型中定义一个访问器,我们希望从中访问属性:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Game extends Model
{
    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    public function getSystemAttribute() // the name can be anything e.g getFooAttribute
    {
        return $this->pivot->system;
    }
}

2) (to avoid getting NULL!)Add the attribute name to the appends property on the model (see here).

2) (避免获得 NULL!)将属性名称添加到模型的 appends 属性(请参见 此处)。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = ['system']; 
}

3) Now you can access that new created systemattribute from the parent Model:

3)现在您可以system从父模型访问新创建的属性:

$user = App\User::find($id);
foreach ($user->games as $game)
{
    echo $game->system;
}

Of course, like with every accessor, you might also "alter" the value of the pivot table before accessing it, for instance:

当然,与每个访问器一样,您也可以在访问数据透视表之前“更改”它的值,例如:

public function getSystemAttribute()
{
    return $this->pivot->foo .'Hello word!'; //append the ""Hello word!" string to the end of the `foo` attribute value
}

Finally notice that the name of the accessor can be anythinglike getFooAttribute, getBarAttribute, getBarBazAttribute. In that case the append would be protected $appends = ['foo'];and you could again access the pivot's fooproperty via the parent Model like $game->foo

最后请注意,访问器的名称可以是getFooAttribute, getBarAttribute, 之类的任何名称getBarBazAttribute。在这种情况下,追加将受到保护$appends = ['foo'];,您可以再次foo通过父模型访问枢轴的属性,例如$game->foo

回答by clod986

I found this question interesting, so I started playing around with the code.

我发现这个问题很有趣,所以我开始玩代码。

If you need to access a specific entry, here's my solution:

如果您需要访问特定条目,这是我的解决方案:

public function getSystemAttribute($game){
    foreach($this->games as $value){
        if($value->id==$game->id){
            $value->pivot->system = 'foo';
            $value->pivot->save();
        }
    }
}

which you can simply call with:

您可以简单地调用它:

$user->getSystemAttribute($game)

Regarding the accessor, I couldn't find any other way without itarating the collection. There are prettier ways of iterating the collection, but this was not the scope of this question. From the documentation, you can see how any attribute of the pivot table can be accessed.

关于访问器,如果不迭代集合,我找不到任何其他方法。有更漂亮的迭代集合的方法,但这不是这个问题的范围。从文档中,您可以看到如何访问数据透视表的任何属性。

Hope this helps

希望这可以帮助

回答by Ronald Hulshof

If you would like to be able to insert your mutated systemattribute on your Response's (JSON, etc.), then you should add the following to both Models (game + user).

如果您希望能够system在您的响应(JSON 等)中插入您的变异属性,那么您应该将以下内容添加到两个模型(游戏 + 用户)中。

protected $appends = array('system');

回答by Marcel Gwerder

My main problem Is that I have some json encoded objects stored as text in my pivot table. I would like to automatically encode and decode them.

我的主要问题是我有一些 json 编码的对象作为文本存储在我的数据透视表中。我想自动编码和解码它们。

So what I came up with, because of the lack of a real alternative, is a basic workaround for the accessor (json decode) functionality. I've first tried to use the approach provided by Collin Jamesbut didn't like the fact that it creates a new custom attribute instead of manipulating pivot->random_attribute.

因此,由于缺乏真正的替代方案,我想出了访问器(json 解码)功能的基本解决方法。我首先尝试使用Collin James 提供方法,但不喜欢它创建一个新的自定义属性而不是操作pivot->random_attribute.

In my tables I allways have an idattribute, so I wrote an accessor for the id attribute and included the pivot data manipulation.

在我的表中,我总是有一个id属性,所以我为 id 属性编写了一个访问器,并包含了数据透视表操作。

public function getIdAttribute($id) {

    //Decode random_attribute
    if(isset($this->pivot->random_attribute)) {
        $this->pivot->random_attribute = json_decode($this->pivot->random_attribute);
    }

    return $id;
} 

Unfortunately I couldn't manage the mutator in a similar way. But for me the accessor is a lot more important.

不幸的是,我无法以类似的方式管理 mutator。但对我来说,访问器更为重要。