2015-12-29 3 views
0

Просто интересно, возможно ли, что какой-то findOrNew для отношений существует в Eloquent (в случае, если отношения не существуют, присоединяют новый экземпляр модели)?Laravel 5. findOrNew для отношений

Что это значит: Допустим, что у нас есть таблицы устройств и спецификаций. Устройство относится к спецификации. Specification_id - это FK (знайте, что это не лучший подход, но у меня что-то вроде этого осталось от предыдущего программиста). В id 11 у нас есть устройство, у которого нет спецификации, но мы должны показать это для пользователя в любом случае.

$device = Device::find(11); 
echo $device->specification->cpu; 

В этом случае он будет выдавать ошибку, потому что спецификация будет нулевой - это не существует для устройства с идентификатором 11.

Знайте, что я мог проверить первый, если он существует, но есть аа много схожего линий и приложений довольно большой. Мне нужно переместить его из Коханы в Ларавел. Он работает в Kohana, потому что пустой объект загружается, а вторая строка возвращает null. Для Laravel я могу просто проверить, существуют ли отношения и загружать новую модель, но я любопытство, если, может быть, есть какой-то другой и лучший способ?

+0

Возможный дубликат [Null шаблона объекта с отношениями красноречивый] (http://stackoverflow.com/questions/33085339/null-object-pattern-with-eloquent-relations) – patricus

ответ

2

Я хотел бы пойти на создание дополнительного метода в Device модели таким образом:

public function getSpecification() 
{ 
    if ($device->specification) { 
     return $device->specification; 
    } 
    return Specification::find(20); // some default specification 
    // or 
    // return new Specification(['cpu' => 'Not provided']); 
} 

И теперь вы можете использовать его таким образом:

$device = Device::find(11); 
$device->getSpecification()->cpu; 

Конечно, это зависит, как вы должны использовать Это. Если у вас много свойств, вы должны запустить этот метод только один раз для того, чтобы объект не запускал несколько запросов, и в случае, если вы будете использовать его для больших коллекций, вы также должны переосмыслить улучшения для более низких запросов к базе данных.

1

Это не совсем создать связанный объект, как вы просили, но для целей вывода данных или тиражирования нулевого выхода Кохан в отсутствии соответствующей модели, я склонен использовать data_get() или object_get() помощников для этой цели ,

$device = Device::find(11); 

echo object_get($device->specification, 'cpu'); 

// You could probably do this too (untested) 

echo object_get($device, 'specification.cpu'); 

Имея немного внешний вид, вы можете переопределить метод getRelationshipFromMethod() в Illuminate\Database\Eloquent\Model

protected function getRelationshipFromMethod($method) 
{ 
    // Different relationships return different types of data so 
    // tweak this as necessary. In theory you only care if the relationship 
    // type is a single entity rather than a collection. 
    $results = parent::getRelationshipFromMethod($method); 

    if ($results instanceOf Illuminate\Database\Eloquent\Collection) { 
     return $results; 
    } 

    // Generate a null value for any missing attributes 
    // PHP7 anonymous class. Return a real class < 7.0 
    return $this->relations[$method] = new class { 
     public function __get($attribute) { 
      return null; 
     } 
    }; 

    // Or perhaps actually create a relationship with a specification 
    $this->relations[$method] = Specification::where('default', true)->first(); 

    $this->specification()->associate($this->relations[$method]); 

    return $this->relations[$method]; 
} 
+0

Выглядит как хороший способ пойти (переопределить). Я изменил условие на то, что ($ result) соответствует всем случаям, когда была найдена связь (один результат не является коллекцией). К сожалению, он не будет работать, когда будет загружаться. Придется углубиться в нее глубже ... – Grzesiek

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