Select specific columns from two related tables

Asked

Viewed 874 times

3

I have an N x 1 relationship, Post x User, have a relationship like the following:

Post.php (model):

....
public function user() {
    return $this->belongsTo('User');
}
....

What I want is to select the id and the username of the model User when I access the Post, but I also want to select only the id and title of the model Post (do not want to select all columns).

With this solution:

return Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();

Yes returns the id and username of User of each Post, to then select the id and the title of Post tried:

return Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->select(['id', 'title'])->get();

But without success, returning the User a null. I am using Laravel 5.5 if relevant.

Note: I don’t want anything 'hard coded' in the models file, because I may want different columns in different locations, preferably I would really like the ratio declared in Post.php remained.

  • I did a test with a similar situation and your code is correct. What error, is returning null?

  • 'Error', is when I try to select also only a few columns columns of the post @Andréluizdegusmão . In my second scenario the id and the title return correctly but the user is null

  • You can post both Models and the two tables?

  • @Virgilionovic, there’s not much more in my models. This is for a json answer (if relevant), I’m not using Lade.

  • @Hulahula I know the problem I’m going through in an answer is already ready

2 answers

1

I took the test with a 1xN relationship to simulate your problem and I believe your code is correct. Just need to insert foreign relationship key.

I would make a modification in arrays too

Post::with(['user'=>function($query){
    $query->select('id','username');
}])->select('id', 'title', 'user_id')->get();

Another alternative you can choose is to create the query through the class DB. Let’s say the class Post is related to table posts and the class User is related to table users, you can write the same query above so:

DB::table('posts')
    ->join('users', 'posts.user_id', '=', 'users.id')
    ->select('users.id as user_id', 'users.username', 'posts.id as post_id', 'posts.title')
    ->get();
  • Thank you, but we had to select the user_id also of the model Post, is +1 for the second second solution

  • But it has two ids on the solution I posted, the post post_id and that of the user user_id.

  • There is in the second alternative, but I prefer to use eloquent whenever possible

  • @Andréluizdegushand your first code has to have the key that corresponds to the relationship of Post with User, that’s why you can not bring the information in your code is equal to the question and is not the solution, the second is not what he wants, but, is a good option. I’m just saying this so you can put the remaining key, because, if not the answer is somehow wrong. In addition to my reply there is a link https://stackoverflow.com/questions/47045440/select-specific-collumns-from-both-related-tables-models?noredirect=1#comment81038448_47045440 which also says the same thing on Soen

  • Pronto @Virgilionovic, I agree with you, so other people who access will only see correct answers.

  • @Andregusmao the problem are those who will give you negative votes ... for me those are the ones you have to stay tuned.

Show 1 more comment

1


It’s like this, when the Eloquent makes the relationship and carries the relationship, the keys that relate should be contained in the results of the SQL, because, these values are used to load relationships, and apparently in your question this was deleted, ie the key was not mentioned in SQL and this implies not to bring the data of the relationship, an example in SQL for you to have an idea of how it works, example:

Post::with('user')->get();

this command generates an SQL like this:

SELECT * FROM `posts`

in the outcome of that SQL brings all the fields user_id (standard nomenclature of Eloquent) with these values and executes one more SQL

SELECT * FROM `users` WHERE id IN [aqui todos os valores de `user_id`]

as in your question not the key so will not show anything even can not after this make the correlation with the results of the first SQL.

The solution

Pass the key on select of Post, example:

return Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->select(['id', 'title', 'user_id'])->get();

Using the Tinker the result of all this was what is explained:

>>> App\Models\Post::with(['user' => function($q) { 
      return $q->select('id','name');}]
    )->select('id','title','user_id')->get();

string(44) "select `id`, `title`, `user_id` from `posts`"
array(0) { }
string(61) "select `id`, `name` from `users` where `users`.`id` in (?, ?)"
array(2) { [0]=> int(1) [1]=> int(2) }

References:

  • 1

    Virgilio, thank you. That’s right: https://stackoverflow.com/questions/47045440/select-specific-collumns-from-both-related-tables-models?noredirect=1#comment81038448_47045440 :P

Browser other questions tagged

You are not signed in. Login or sign up in order to post.