How to get only selected column in a child related model? - laravel

I have two models, User and Post, where a User can have multiple Post models. In my application, I only want to retrieve the title column from the related Post model when querying for a User. Here is my current code:
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
Here is what I have tried to retrieve the title column for the related Post models:
$user = User::with('posts:title')-\>get();
However, this retrieves all the columns for the Post model. How can I modify my code to only retrieve the title column for the related Post models? Thank you!

try this
$user = User::with(['posts' => function ($query) {
$query->select('title');
}])->get();

If you want to get the data with selected column you also need to pass the FK to identify its relationship.
The example below tells the the post also need the user_id column to identify the relationship between POST and USER model
$user = User::with('posts:title,user_id')->get();

Related

In which Controller should I write logic for Models that are in a relationship

I am making a blog with users who each have posts. Naturally, I have a UserController, PostController, and a User and Post model.
The User model has a one-to-many relationship with the Post model like so
// User Model
public function posts()
{
return $this->hasMany('App\Post');
}
I would like to get all the posts of a specific user by using
// UserController or PostController...
$posts = User::find($id)->posts()->get()
Should I write this logic in my UserController (because it uses the User model) or should I write the logic in my PostController (because it returns posts)?
Actually, you just need to create the relationship as you did, and then you will be able call it wherever you want, just like as you described, with User::find($id)->posts()->get().
So, if you need to return a user's post on a view, for instance, you can do something like that on your UserController:
public function postsView(User $user)
{
$posts = $user->posts()->get();
return view('user.posts', compact('posts'));
}
Also, if you want the other way around (to know who is the user behind the post), you can create a relationship on your Post model using belongsTo().
// Post Model
public function user()
{
return $this->belongsTo('App\User');
}
You can write the query anywhere in UserController or PostController
$user = User::with('posts')->whereId($id)->first();
echo '<pre>';
print_r($user->toArray());
exit;
You'll get user with all posts
In your Model User put the relationship.
public function posts()
{
return $this->hasMany('App\Post','foreign_key','local_key');
}
In your UserController or PostController get the results by using
$posts = User::find($id);
foreach($posts->posts as $post)
{
echo $post->title;
}
You can query from both controllers. From where you want to query the relationship depends on where and how you want to fetch data from.
For example, if you are showing posts related to user on a user profile page with other bio data etc then you will call the relationship in UserController.
On other hand, let's say you want to show posts related to an author on a search page then it will be better to have the posts queried via relationship in PostController.
In short, it's a choice based on convenience and optimization to be made.

How get users from section table ? laravel

The idea is that I have relation between two table's section and user
the section_id exist in users table it relation with id section
SO for ex : section_id = 2 > want to bring all users belongs to id section
My code here use id from url and I don't want to do this I want without id bring all users :
public function getAllUsers($id)
{
$data = User::where('section_id',$id)->get();
}
If I'm understanding you correctly, you want to get all the users for a particular Section that have the relationship to that section.
Assuming you have the relationship set up correctly on the Section model:
public function users() {
return $this->hasMany('App\User');
}
I suggest you go about this 'backward' and just pull the users from the Section model itself (eager loading allows one query):
$section = Section::with('users')->first();
$usersForThisSection = $section->users;
If you setup a One to Many relationship you can say things like: $user->section to return the section a user belongs to...and $section->users to get a collection of all the users in a section -- the getAllUsers() is redundant in this case.
Make sure your User and Section models contain these methods. Sounds like your migration was setup properly if you have a section_id column on your users table.
More info on one-to-many here: https://laravel.com/docs/5.8/eloquent-relationships#one-to-many
// app/User.php
class User extends Model
{
public function section() {
return $this->belongsTo('App\Section');
}
}
// app/Section.php
class Section extends Model
{
public function users() {
return $this->hasMany('App\User');
}
}
Test out your relationships in php artisan tinker like so...
$user = User::find(1);
$user->section
$section = Section::find(1);
$section->users
you need a unique identifier to receive section_id's users. receive it from url(get) or ajax(post) . if you worry about users access then use "auth"

Laravel Relationships: hasManyThrough, belongsTo, belongsToMany

Heyy, I have a Laravel project here, can u guys help me with this question about relationship?
I have the following database structure:
users
id
name
email
password
event
id
description
city_id
block_range
id
event_id
user_block_ranges
user_id
block_range_id
Explanation
users: A normal user authentication table. (has a belongsToMany relationship with user_block_ranges)
event: Stores event info. (has a hasMany relationship with block_range)
block_range: Save blocks of time of event. (has a belongsTo relationship with event)
The real question is: how do I get all the events of the user? Through the user_block_ranges then block_range relationship? Maybe using hasManyThrough?
Thanks in advance.
I believe your models look like this:
User model
class User extends Model
{
public function blockRanges()
{
return $this->belongsToMany('App\BlockRange', 'user_block_ranges', 'user_id', 'block_range_id');
}
}
Block Range model
class BlockRange extends Model
{
public function event()
{
return $this->belongsTo('App\Event');
}
}
To get all events of the user you can do this:
$user = App\User::find(1);
$events = array();
foreach ($user->blockRanges as $block_range) {
$events = $block_range->event;
}

Laravel - two columns with relationship to the same column in another table

I set up a one-to-many Eloquent relationship between User and Credit
User
id | name
Credit
id | recipient | author | amount
where
recipient is user.id
author is user.id
In Laravel, the relationship for recipient is established:
class Credit extends Model {
public function user() {
return $this->belongsTo('App\User', 'recipient');
}
}
But how do I add the relationship for author as well?
I tried:
class Credit extends Model {
public function recipient() {
return $this->belongsTo('App\User', 'recipient');
}
public function author() {
return $this->belongsTo('App\User', 'author');
}
}
i.e. I changed user() into two functions: recipient() and author()
But I am getting Trying to get property of non-object, which I think means that using recipient() or author(), Eloquent is unable to "bind" it to my User model.
How do I get around this?
The problem is that you have a field called recipient and a relationship sharing the same name. Consider renaming one of them this is because laravel will use the field instead hence if you do
$credit->recipient->name
you can't access the user table since laravel will load the field. And the field does not have a property called name.
Earlier when the relationship was user() it worked. So consider finding a suitable name to user e.g credit_recipient()

Laravel 4 - Display username based on ID

I have a posts and a users table.
In the posts table, i have a posts_author which is the ID of the user from the users table.
Is there an easy way to display the email address of the user, which is in the users table?
Cheers,
As long as you've set your relationships up it should just be a simple query.
http://laravel.com/docs/eloquent#relationships
Look at the one to many relationships.
(1 User, Multiple posts)
Remember to set the inverse of the relationship up also
If your model has the right relationships then should be as simple as $post->author->email().
You must tweak the author relationship because Eloquent assumes the key will be named author_id.
// Post
public function author() {
return $this->belongsTo('Author', 'posts_author');
}
// Author
public function posts() {
return $this->hasMany('Post');
}
Remember to use eager loading in case you are retrieving emails from more than one post object, or you will end up with n+1 queries.
Providing that you've configured the relationships properly, it should be pretty easy.
Post Model:
class Post extends Eloquent
{
protected $table = 'posts';
public function author()
{
return $this->belongsTo('User', 'posts_author');
}
}
Then User Model:
class User extends Eloquent
{
protected $table = 'users';
public function posts()
{
return $this->hasMany('Post', 'posts_author');
}
}
Then when loading the post you can do the following.
$post = Post::with('author')->find($id);
This will tell Eloquent to join on the users table and load the user data at the same time. Now you can just access all of the user information like this:
$post->author->username;
$post->author->email;
$post->author->id;
// etc etc
Obviously this is just a skeleton, but the assumption is that you have the rest setup.

Resources