'Laravel, get relation row instead of id

I want to get author row instead of author_id. I could this with add collection and change one by one but has Laravel any function for this? Well, I want make this one line Can i use something like this

Book::where('id',$bid)->with('author')->first('author_id AS author'); //Changes only coulmn name :(

model

public function author()
    {
        return $this->hasOne(Author::class,'id','author_id');
    }

query

Book::where('id',$bid)->with('author')->first()

Output

  {
    "id": 1,
    "name": "Book 1",
    "author_id": 3,
    "category_id": 2,
    "level_id": 1,
    "book_language_id": 1,
    "book_length": 0,
    "img": "book1.png",
    "summary": "Summary 1",
    "rate_avg": "2.75",
    "created_at": "2022-03-04T18:46:32.000000Z",
    "updated_at": "2022-03-04T18:52:28.000000Z",
    "author": {
        "id": 3,
        "name": "Author 3",
        "created_at": "2022-03-04T18:46:32.000000Z",
        "updated_at": "2022-03-04T18:46:32.000000Z"
    }
}

Want

{
    "id": 1,
    "name": "Book 1",
    "author": {
        "id": 3,
        "name": "Author 3",
        "created_at": "2022-03-04T18:46:32.000000Z",
        "updated_at": "2022-03-04T18:46:32.000000Z"
    },
    "category_id": 2,
    "level_id": 1,
    "book_language_id": 1,
    "book_length": 0,
    "img": "book1.png",
    "summary": "Summary 1",
    "rate_avg": "2.75",
    "created_at": "2022-03-04T18:46:32.000000Z",
    "updated_at": "2022-03-04T18:52:28.000000Z",
    
}


Solution 1:[1]

in your query

Book::where('id',$bid)->with('author')->first()

you are getting the book that has that id and you are eager loading the author relation, so in order to get the author you have to access the author field:

Book::where('id',$bid)->with('author')->first()->author

Solution 2:[2]

As I said I can this with collection like this:

$b=Book::where('id',$bid)->with('author')->first();

                    $book=collect([
                        'id'=>$b->id,
                        'name'=>$b->name,
                        'author'=>$b->author,
                        'category_id'=>$b->category_id,
                        'level_id'=>$b->level_id,
                        'book_language_id'=>$b->book_language_id,
                        'book_length'=>$b->book_length,
                        'summary'=>$b->summary,
                        'rate_avg'=>$b->rate_avg,
                    ]);

But this method seems unnecessary

Solution 3:[3]

In your example the only difference between the output and what you want is "author_id": 3, as been deleted.

So if you don't want a column or rename a column, you need to use ->select and take all the field you want. And you can also rename with something like that

-> select(DB::raw('author_id as auhtor'), 'books.*')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mike
Solution 2 Starrk
Solution 3 marc_s