2013-06-19 2 views
14

В настоящее время у меня есть несколько моделей, которые имеют много разных отношений через laravel. вот структура:Использование аксессуаров с полями сводных таблиц в Eloquent

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

Теперь это все работает отлично. Тем не менее, я хочу использовать мутатор в поле системы из сводной таблицы. Я не могу найти любую документацию на этом и следующем (в оба пользователя и игровые модели) не работает:

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

вы можете сбросить данные таблицы –

+0

я могу это сделать, но это очень простой. – euantorano

ответ

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) 

Что касается аксессор, я не мог найти другим способом без повторения коллекции. Есть более красивые способы итерации коллекции, но это не вопрос этого вопроса. Из documentation вы можете увидеть, как можно получить доступ к любому атрибуту сводной таблицы.

Надеется, что это помогает

+0

Спасибо! Я смотрел вокруг как сумасшедший, чтобы добавить данные в сводную таблицу, а не получить доступ к ней, и ничего не мог найти. Все дело только в том, чтобы привязать ось, не заботясь о столбцах данных ... –

8

Я не проверял, но это должно работать.

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

... 

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

Значение, которое передается, вытягивается из атрибутов моделей. Нет системного атрибута, поэтому вы должны получить NULL. Мы можем просто игнорировать это и напрямую вытащить значение из сводной таблицы.

+1

Вам не нужен аргумент $ value. –

+0

Чтобы получить доступ к атрибуту * system * (в представлениях/контроллерах), вам необходимо добавить имя атрибута в свойство 'appends' вначале модели – ira

1

Если вы хотите, чтобы у вас был установлен мутированный атрибут system в вашем ответе (JSON и т. Д.), Вы должны добавить следующие модели для обеих моделей (игра + пользователь).

protected $appends = array('system'); 
+1

. Только для записи это допустимо, если вы используете Laravel> = 4.0 +0,8. Кроме того, для этой директивы вам понадобится атрибут атрибута «system» для этой директивы. – Gadoma

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

К сожалению, я не мог управлять мутатором аналогичным образом. Но для меня аксессуар намного важнее.

1

Необходимо определить аксессор для свойства system объекта pivot, а добавить имя атрибута в свойство добавлений на модели.Вся процедура следует

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) (чтобы избежать NULL) Добавить имя атрибута! к добавлению свойства на модель (см. here).

<?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) Теперь вы можете получить доступ к этому новому созданному 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 
} 

Наконец заметить, что имя аксессора может быть что угодно, какgetFooAttribute, getBarAttribute, getBarBazAttribute. В этом случае Append будет защищен $appends = ['foo']; и вы могли бы снова открыть foo свойство Pivot с помощью родительской модели, как $game->foo

Смежные вопросы