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

时间:2013-06-19 16:10:00

标签: laravel laravel-4 eloquent

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

users
    id
    username
    ...

games
    id
    title
    ...

game_user
    game_id
    user_id
    system

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

<?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');
    }

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

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

5 个答案:

答案 0 :(得分:9)

我没有测试过,但这应该可行。

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

...

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

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

答案 1 :(得分:2)

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

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

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

您只需拨打电话:

$user->getSystemAttribute($game)

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

希望这有帮助

答案 2 :(得分:2)

您需要为数据透视的xhdpi属性定义访问者,并将属性名称添加到模型的附加属性。整个过程如下:

1)在我们想要访问属性的父模型中定义一个访问者:

system

2) (以避免获取NULL!) 将属性名称添加到模型的appends属性中(参见here)。

<?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;
    }
}

3)现在,您可以从父模型中访问新创建的<?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']; } 属性:

system

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

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

最后请注意,访问者的名称可以是任何,例如public function getSystemAttribute() { return $this->pivot->foo .'Hello word!'; //append the ""Hello word!" string to the end of the `foo` attribute value } getFooAttributegetBarAttribute。在这种情况下,附加内容将受到保护getBarBazAttribute,您可以再次通过父模型$appends = ['foo'];

访问数据透视图的foo属性

答案 3 :(得分:1)

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

protected $appends = array('system');

答案 4 :(得分:0)

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

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

在我的表中,我总是有一个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;
} 

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