2015-02-04 3 views
3

У меня есть модель под названием Book, и я хочу добавить дополнительный столбец к SQL по умолчанию.Eloquent model add extra column по умолчанию

В настоящее время SQL по умолчанию выглядит следующим образом:

SELECT * FROM `books` 

Но я хочу SQL по умолчанию, чтобы выглядеть следующим образом:

SELECT *, "Hello" as `greeting` FROM `books` 

Так что я могу сделать следующее:

// in a controller function... 
$book = Book::find(1); 
echo $book->greeting; // Hello 

$books = Book::all(); 
foreach($books as $book){ 
    echo $book->greeting; // Hello 
} 

Есть ли способ достичь этого?

Большое спасибо

+3

Почему вы просто не добавляете это к самому определению класса, а не притворяетесь, что это происходит из SQL динамически? Похоже, вы, по сути, должны скрывать собственность от того места, где она должна быть действительно определена. –

+3

Это упрощенный пример. То, что я пытаюсь сделать, - это добавить новый атрибут 'score' для моей модели. Атрибут 'score' рассчитывается как сумма голосов в другой таблице. Полученный SQL-код довольно сложный, и я не хотел его отвлекать от вопроса, а именно, как добавить дополнительные столбцы SQL в запрос по умолчанию модели. –

+0

Почему бы вам тогда не связать модель книги с моделью оценки для этой цели? Возможно, вы также получите гораздо более релевантные ответы на ваш фактический случай использования, если вы действительно объяснили этот случай использования в своем вопросе. –

ответ

7

Даже если мне интересно, что причиной этого является, вы можете переопределить newQuery в модели

public function newQuery(){ 
    $query = parent::newQuery(); 
    return $query->selectRaw('*, "Hello" AS greeting'); 
} 

Другим способом было бы использовать scope:

public function scopeWithGreeting($query){ 
    return $query->selectRaw('*, "Hello" AS greeting'); 
} 

Использование:

$book = Book::withGreeting()->find(1); 

Если вы действительно хотите область действия каждый раз, вы можете использовать global scope, поэтому вам не нужно постоянно звонить withGreeting.

+0

Это 'scopeWith ...' похоже, что это может быть жизнеспособным способом достижения того, что я ищу! Спасибо. –

+0

Добро пожаловать. Сообщите мне, если вам нужна дополнительная информация ... Кстати, вы можете называть область видимости тем, что хотите. Просто добавьте 'scope' для имени метода – lukasgeiter

+0

Хотелось бы, чтобы вы не предполагали, что с" Even хотя мне интересно ... ». Есть миллион и одна причина, по которой изменение инструкции SQL лучше, чем lettin g Ларавель делает ногу. Тем не менее, ваш ответ - лучшее решение, с которым я столкнулся. 'newQuery()' похоже, все! – cartbeforehorse

0

Я думаю, что ORM не сможет справиться с этим достаточно хорошо, так что вы скорее столкнетесь с проблемами раньше, чем когда-либо, если вы не можете изменить свою модель книги, но все же хотите сделать это, я предлагаю вам создать новая модель, указывающая на вид, построенный с использованием

SELECT *, 'Hello' as `greeting` FROM `books` 
+0

Это идея. Однако проблема заключается в том, что вы не можете использовать ту же модель для обновления представления (поскольку представления не обновляются в целом). Это может сделать это решение громоздким. – cartbeforehorse

2

Использование an accessor. Это один возвращает «Hello» для $book->greeting, если модель не имеет поздравительную набор:

public function getGreetingAttribute($value) { 
    if(empty($value)) { return 'Hello'; } else { return $value; } 
} 
+0

Спасибо, но я специально хочу, чтобы этот дополнительный атрибут пришел из SQL-запроса. –

+0

@ThomasClayson Почему вас волнует, из любопытства? – ceejayoz

+1

@ceejayoz [См. Комментарий OPs] (http://stackoverflow.com/questions/28324963/eloquent-model-add-extra-column-by-default/28325110#comment44997926_28324963) – lukasgeiter

0

Вы можете использовать $appends Вот пример

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Book extends Model 
{ 
    /** 
    * The attributes that are mass assignable. 
    * 
    * @var array 
    */ 
    protected $fillable = [ 
     'name', 
    ]; 

    /** 
    * The accessors to append to the model's array form. 
    * 
    * @var array 
    */ 
    protected $appends = ['greeting']; 

    public function getGreetingAttribute() 
    { 
     return 'Hello'; 
    } 
} 

Вам не нужно писать SQL для этого см. больше https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L59-L64