Как создать акксессор только для Pivot таблицы?
В настоящее время у меня есть несколько моделей, которые имеют полиморфные отношения многие ко многим. Вот структура:
sections
id
name
handbooks
id
name
properties
id
name
type(list, number, string, file)
property_bindings
id
model_id
model_type (handbook or section)
property_id
elements (through the section gets properties to fill)
id
name
section_id
property_value
id
model_id
model_type (element or another model )
property_id
value (for properties of the file type I store the record id from the table files)
class Section extends Model
{
public function properties()
{
return $this->morphToMany('App\Property', 'model', 'property_bindings')->withTimestamps()->orderBy('sort');
}
public function elements() {
return $this->hasMany('App\Element');
}
}
class Element extends Model
{
public function propertyValues()
{
return $this->morphToMany('App\Property', 'model', 'property_values')->withPivot('id','value')->withTimestamps();
}
public function section() {
return $this->belongsTo('App\Section');
}
}
У меня нет проблем с получением и изменением данных в таблицах. Но при выводе записей из таблицы 'elements' мне нужно преобразовать значения ее свойств для отображения на фронте, я пытался сделать это через модель свойств
class Property extends Model
{
public function getValueAttribute($value) {
if (empty($this->pivot)) return null;
$id = $this->pivot->id;
$value = $displayValue = $this->pivot->value;
if($this->isTypeFile()) {
$file = File::find($value);
if($file) {
$displayValue = File::getUrlFile($file);
}
}
if($this->isTypeNumber()) {
$displayValue = (int)$value;
}
if ($this->isTypeList()) {
$displayValue = PropertyEnum::find($value)['value'];
}
return [
'id' => $id,
'original' => $value,
'display' => $displayValue
];
}
}
Для элементов это работает хорошо, но атрибут 'value' также появился когда я получая свойства для секций.
$element->propertyValues выводит [{"id":1,"name":"width","value":{"id":24,"original":"20","display":"20"}...
$section->properties выводит [{"id":1,"name":"width","value":{"id":null,"original":"null","display":"null"}...
Проблема еще в том что на некоторых страницах мне нужно совмещать эти два массива, и присваивать value вручную, а из за наличия аксессора laravel не присваивает новое значение.
$sectionProperties = $element->section->properties;
$elementPropertyValues = $element->propertyValues;
$properties = array();
foreach ($elementPropertyValues as $elementProperty) {
$value = $elementProperty->value;
if($elementProperty->isMultiple()) {
if(!array_key_exists($elementProperty->id, $properties)) {
$properties[$elementProperty->id] = array();
}
array_push($properties[$elementProperty->id], $value);
} else {
$properties[$elementProperty->id] = $value;
}
}
foreach ($sectionProperties as $property) {
if(!empty($properties[$property->id])) {
$property['value'] = $properties[$property->id];
}
}
Есть ли какое нибудь решение, в котором при вызове $section->properties у него не будет атрибута value, а при вызове $element->propertyValues будет.