Select specific columns on eager loading polymorphic relationships - Laravel - php

In a "normal" relationship I can do something like this to select only a few columns while eager loading (using with):
->with(['reported' => function ($query) { $query->select(['nick','id']); } ])
But how to do it when working with polymorphic relationship where the columns i want to select are different according to the model morphed?
I have already tried using the query like a normaly do, also tried using a morph clause, but there is no select funciton on it.
--
Edited:
ReportMessages (model)
public function author(){
return $this->morphTo();
}
User (model)
protected $fillable = ['name', (...)];
public function reportMessages(){
return $this->morphOne('App\ReportMessage', 'author');
}
Jogador (model)
protected $fillable=['nick', (...)];
public function reportMessages(){
return $this->morphOne('App\ReportMessage', 'author');
}
And i want to select (when eager loading) only the nick ,when it is Jogador model that is morphed, and only the name, when User is the model morphed.

Try this
$query->with(['reported' => function($query){ $query->select(['id','nick']) } ])->orderBy('created_at', 'ASC');

Related

Laravel : Use Pivot table to get group with their respective roles

I'm trying to get All roles in a user group in eloquent style.
//this function is defined in the ModelUserGroup
public function roles(){
return $this->hasMany(ModelGroupRole::class, 'group_id','id');
}
I'm trying to get all roles like this:
ModelUserGroup::with('roles')->get(),
I also tried ->hasManyThrough but it is not working for me.
I need all roles data like id,name, etc. using with.
Looks like you need a belongsToMany relationship.
In your UserGroup model.
public function roles()
{
// Assuming your role model is named ModelRole...
return $this->belongsToMany(ModelRole::class, 'group_role', 'group_id', 'role_id');
}
Now you can do the following:
$group = ModelUserGroup::with('roles')->first();
dd($group->roles); // will be a collection of ModelRole's
Answered on my phone so there may be syntax errors.
As stated here in the many to many section, you have got to define the relationships as the follwing:
in User_Group :
public function roles(){
return $this->belongsToMany('App\Pathto\Role', 'group_role','group_id','role_id');
}
in Role:
public function user_groups(){
return $this->belongsToMany('App\Pathto\UserGroup', 'group_role', 'role_id', 'group_id');
}
Edit: ModelUserGroup::with('roles')->get() should work just fine then.
(of course, change pathto with your path to the models.)

Laravel Eloquent belongsto relationship returns null

I have two Eloquent models:
1) Post
class Post extends Model
{
protected $table = 'posts';
protected $fillable = ['id', 'user_id', 'product_id', 'site_id', 'link_id', 'body', 'created_at', 'updated_at'];
public function user(){
return $this->belongsTo(User::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
2) Product
protected $table = 'products';
protected $fillable = ['id', 'user_id', 'manufacturer_id', 'shift_product_id', 'name', 'english_name',
'slug', 'text', 'spec', 'live', 'created_at', 'updated_at'];
public function posts(){
return $this->hasMany(Post::class);
}
I need to get the product from a post
I do that:
$posts = Post::get();
foreach($posts as $key){
dd($key->product);
}
Like this it returns NULL
If I do like this:
dd($key->product());
I get the product but I can't to use that
but I need to get something like that to use whant I need:
Try to point out foregin key and other key in relation, examples:
public function post()
{
return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
}
public function user()
{
return $this->belongsTo('App\User', 'foreign_key', 'other_key');
}
More: https://laravel.com/docs/5.5/eloquent-relationships
i found my problem
i dont have in the DB product with ID = 1
:/
stuped problem
thanks for all the help i leran alot from u.
The relationship probably doesn't exist in the database.
Based on your fillable array on Post, the way you have the relationships setup looks correct as you are following naming conventions for keys and your belongsTo relationship methods have the correct name for convention.
$post->product() is not returning your Product model. It is returning a Relation type object (BelongsTo). This is used for querying the relationship. $post->product would be the dynamic property for the relationship that would return the already loaded relationship or load the relationship and give you the result.
Laravel 5.5 Docs - Eloquent - Relationships - Relationship Methods Vs. Dynamic Properties
If the relationships are setup correctly $post->product being null would mean the relationship doesn't actually exist in the database, no matching id in products for product_id or product_id being null. (assuming no foreign key constraint)
Side note: eager loading the relationship would be a good idea:
$posts = Post::with('product')->get();
I just came across this post because I got a similar error while working on a project.
What I discovered is that when you query a model with the all() method, it ignores the related softdeleted rows.
When you try to access them tho, you get the null
Remember to hit save() after associate and dissociate. Got me a couple of times:
$model->relation()->associate($record)->save();

Laravel 5 – get particular many to many relation based on model and related model ID

I've got Tag and Attendee Eloquent models, they are in many-to-many relation. Pivot table has also two more attributes – value_int and value_string. My Attendee model looks like this:
class Attendee extends Model
{
public $timestamps = false;
protected $fillable = [
'event_id'
];
public function tags() {
return $this->belongsToMany('App\Models\Tag', 'attendee_tag', 'attendee_id', 'tag_id')
->withPivot(['value_string', 'value_int']);
}
public function scoreTagValue($tag_id) {
return $this->tags->where('tag_id', '=', $tag_id)->first();
}
}
What I want is to obtain pivot values based on Attendee model and variable tag_id, so I've written scoreTagValue function, but it always returns null and I don't know why :( I'm calling it this way:
$attendee->scoreTagValue($tag_id). Thanks for your help :)
You need to access the relation, not the property:
public function scoreTagValue($tag_id) {
return $this->tags()->where('tag_id', '=', $tag_id)->first();
}
Also, according to the docs, withPivot() does not take an array, so:
->withPivot('value_string', 'value_int');

Laravel 5.4 relationship

Hi I need to display users items from table name Items.
I have 3 models.
User model:
public function userItem()
{
return $this->hasMany('App\UserItem', 'item_id');
}
UserItem model:
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
What to write to Item Model to make this relationship successful. So I could display items from items table.
If I now do this:
I get info from user_items table from DB.
when I do this #foreach(Auth::user()->userItem as $item) I get this:
Column not found: 1054 Unknown column 'user_items.user_items' in
'where clause'
I think you want to use many to many relation
you have 2 models User and Item
and 3 tables : -users -items -user_items
User Model should be like this:
public function userItem()
{
return $this->belongsToMany('App\Item','user_items','user_id','item_id');
}
and Item Model:
public function user()
{
return $this->belongsToMany('App\User','user_items','item_id','user_id');
}
and you need a table that you named it user_items
and you dont need to define userItem model you can remove relations in this model
in your blade use this code:
#foreach(Auth::user()->userItem as $item)
You are exhibiting a many-to-many relatioship, and yet using methods for one-to-many relationships. For a many to many relationship, use the following code in your models:
//user model:
public function userItem()
{
return $this->hasMany('App\UserItem', 'user_items', 'user_id', 'item_id');
}
//userItem Model:
public function user()
{
return $this->hasMany('App\User', 'user_items', 'item_id', 'user_id');
}
For a many-to-many relationship, you need a hasMany method on both your models.
For information on the parameters to the hasMany method as well as other information on many-to-many relationships, please read the documentation on many-to-many relationships: https://laravel.com/docs/5.4/eloquent-relationships#many-to-many
Hope this helps.

how to convert joins query to laravel eloquent query

I have query bulider's query like this
$schedule = DB::table('users')
->join('tblHomeCourts','users.homeCourtId','tblHomeCourts.homeCourtId')
->join('tblUserHomeCourts','tblUserHomeCourts.userId','users.userId')
->join('tblSchedules','tblUserHomeCourts.userHomeCourtId','tblSchedules.userHomeCourtId')
->select('tblHomeCourts.homeCourtName', 'tblHomeCourts.address','tblSchedules.timeFrom','tblSchedules.timeTo','tblSchedules.duration','tblSchedules.scheduleStatus','users.firstName','users.lastName','users.profilePic','users.userId')
->where(['tblSchedules.scheduleStatus'=> 0,
])->where('timeFrom','>',$request->currentTime)
->where('timeTo','>',$request->currentTime)
->where('tblUserHomeCourts.homeCourtId',$homeCourtId)
->get();
Now, I want to convert this into proper eloquent query using eloquent relationship I'm fully messed up with relationships can somebody please help me to find out the solution?
thanks :)
To achieve this we have to define relationships among the related table for the first place. Then we need to load the joint table using the with method.
For example you User model should look like this:
class User extends Model{
protected $table = 'users';
public function homeCourt(){
//Many to one relation between user and homeCourt
return $this->belongsTo(HomeCourt::class, 'homeCourtId', 'homeCourtId');
}
public function userHomeCourts(){
//One to many relation between user nad userHomeCourt
return $this->hasMany(UserHomeCourts::class, 'userId', 'userId');
}
}
Your HomeCourt model should look like:
public class HomeCourt extends Model{
protected $table = 'tblHomeCourts';
public function user(){
//One to many relation between homeCourt and user
return $this->hasMany(User::class, 'homeCourtId', 'homeCourtId');
}
}
Your UserHomeCourt model should look like:
public class UserHomeCourt extends Model{
protected $table = 'tblUserHomeCourts'
public function user(){
//Many to one relation between userHomeCourts and users
return $this->belongsTo(User::class, 'userId', 'userId');
}
public function schedules(){
//One to many relation between userHomeCourts and schedule
return $this->hasMany(Schedule::class, 'userHomeCourtId', 'userHomeCourtId');
}
}
Your Schedule model should look like:
public function Schedule extends Model{
protected $table = 'tblSchedules';
public function userHomeCourt(){
//Many to one relation between schedule and userHomeCourts
return $this->belongsTo(UserHomeCourt::class, 'userHomeCourtId', 'userHomeCourtId');
}
}
Now you are ready to build your query. This query is bit different than the query you have built using query builder. Besides, the output of laravel eloquent query is also different. You have to adjust that result with you view:
You can query like this:
$users = User::with('homeCourt', 'userHomeCourts.schedule')->where('timeTo', '>', ,$request->currentTime)->get();
This query is just an example, you have to define it according to your requirement. Here, the parameters of with methods are the methods name of that users table relation with other tables. This is how it works.
You can read more here: https://laravel.com/docs/5.4/eloquent-relationships

Categories