Reputation: 29925
I have a model called Book
and I want to add an extra column to the default SQL.
At the moment the default sql looks like this:
SELECT * FROM `books`
But I want the default SQL to look like this:
SELECT *, "Hello" as `greeting` FROM `books`
So that I can do the following:
// in a controller function...
$book = Book::find(1);
echo $book->greeting; // Hello
$books = Book::all();
foreach($books as $book){
echo $book->greeting; // Hello
}
Is there any way I can achieve this?
Many thanks
Upvotes: 4
Views: 4992
Reputation: 5166
You can use $appends
Here is the example
<?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';
}
}
You don't need to write any SQL for this see more https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L59-L64
Upvotes: 1
Reputation: 152860
Even though I wonder what the reason behind this is, you could override newQuery
in your model
public function newQuery(){
$query = parent::newQuery();
return $query->selectRaw('*, "Hello" AS greeting');
}
Another way would be to use a scope:
public function scopeWithGreeting($query){
return $query->selectRaw('*, "Hello" AS greeting');
}
Usage:
$book = Book::withGreeting()->find(1);
If you really want the scope every time, you can use a global scope so you don't have to call withGreeting
all the time.
Upvotes: 8
Reputation: 179994
Use an accessor. This one returns 'Hello' for $book->greeting
if the model doesn't have a greeting set:
public function getGreetingAttribute($value) {
if(empty($value)) { return 'Hello'; } else { return $value; }
}
Upvotes: 2
Reputation: 770
I think that the ORM woud not be able to manage that well enough so you are going to get into trouble sooner than later, if you can not modify your book model but still wnat to accomplish that , i suggest you create a new model pointing to a view constructed with
SELECT *, 'Hello' as `greeting` FROM `books`
Upvotes: 0