Laravel column name and relationship name same - laravel

Can I have column name and relationship name same?
example:
I have a column edited_by in mack.php model and I want to get full details of user mentioned in edited_by from users table so i have relationship like below
public function edited_by(){
return $this->hasOne('App\User','id','edited_by');
}
now, if i try to access $model->edited_by->first_name its throwing error 'trying to get property of non-object'
is there any way to fix it other than having different names?

The short answer is no. You can't have them be the same name because the column will always be returned if found and the relationship will never be returned if a column is found with that name.
Changing the column name to user_id would be more appropriate than edited_by. It's more descriptive, and it's also the default id that Eloquent will look for. Similarly the relationship name makes more sense being named user() rather than edited_by() because it returns a user Model.
The slightly longer, and totally incorrect answer is that you can access the relationship with $model->edited_by()->first_name this will result in extra queries being run unnecessarily though.

Related

Laravel 6 check if a json field contains a value in a collection

I am trying to see if a user id is contained in a json field in my laravel collection. In my postgresql database I have a user_id field which contains a list of integers that pertain to my user model and table. I am aware in eloquent I can use the whereJsonContains method but I am not finding an equivalent method for a collection. How can I go about searching this user_id column for a specific user id?
check the manual for the aviable methods list:
https://laravel.com/docs/8.x/collections#available-methods
In your case i guess that is about:
where

What to backfill with in type-column on polymorphic table?

I am changing my File-model to go from one to many to be a one to many polymorphic relation. Before only my User-model could have a file but now my model Guest will also be able to have a file.
So before I had a column in the file table named user_id I have renamed that one following the pattern here: https://laravel.com/docs/7.x/eloquent-relationships#many-to-many-polymorphic-relations
So it is now named fileable_id.
In addition to the renaming I have added a column named fileable_type. I now want to backfill that column so everything existing points on the User-model. What should I write in that column?
I have tried App\User and User without success.
App\User should be correct if that is how you have your User model namespaced. The polymorphich relationships use the getMorphClass() method on the Eloquent model. You can verify this by doing:
$u = new User();
dd($u->getMorphClass());
If you have not created a custom polymorphic type for the User model, then getMorphClass() should be equivalent to User::class.

How to check if one record is attached to another?

I have defined a many-to-many relationship between Student and Seminar models. How can I find out if one particular student is attending one particular seminar? Non-working example of what I want to achieve is illustrated below:
$seminar->students()->contains($student->id);
The following error is shown when using the above code snippet:
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::contain()'
Try instead:
$seminar->students->contains($student->id);
Presuming $student contains an instance of the Student model you can simplify it further and just use:
$seminar->students->contains($student);
When you add parentheses you're using the Laravel query builder, and you never completed the query. To do it in the manner you had originally you would need:
$seminar->students()->get()->contains($student->id);
This method could be useful if you wanted to add constraints when fetching your students.
But generally you can omit the parentheses and a Collection will be returned, allowing you to use methods like contains.
This has the additional benefit of not re-querying the database once the relationship is loaded, so will generally be a far more efficient means of fetching relationships.
If you haven't already loaded the students and want a database efficient method of checking you could instead use:
$seminar->students()->where('students.id', $student->id)->exists();
In your case the exception is you are calling 'contains()' function (which is for Laravel Collection) on 'Query Builder'. It should be
$seminar->students->get()->contains($student->id);
but this is inefficient since this will retrieve all the students of the seminar.
so instead,
$seminar->students()->wherePivot('student_id', $student->id)->exists();
this method will check in the intermediate table of many to many relationship for particular seminar-student pair, and will return whether exists or not.
The accepted answer is wrong. $seminar->students()->exists($student->id) does not check if the relationship exists. It only checks if the student exists. The student could belong to any seminar and it would still return true.
The correct way to check if a relationship exists without fetching records from the database would be:
$seminar->students()->whereId($student->id)->exists()
Check using query
$seminar->students()->whereKey($student->getKey())->exists();
Check after query (angry), can have memory problems if you have multiple attachments
$seminar->students->contains($student->getKey());
// or
$seminar->students()->get()->contains($student->getKey());

Laravel Eloquent : two keys relationship

I have a first table named "Building", and this one gets a Type and a Level. There are multiple building with same type and level.
I have another table named "BuildingInfo", who also gets a Type and a Level. The couple Type/Level is unique on this table.
Is there a way to have a HasOne relationship on Building, giving me the matching BuildingInfo ? The problem being that there are two keys on each table to get it, and I can only specify one key for each table with HasOne().
Thank you.

Eloquent select specific columns

I am trying to select specific columns using Laravel's Eloquent but I am having some issues. I just want to SELECT quantity, prices from prices. I have tried
$prices = Price::select(array('quantity', 'price'))->whereMonthAndYearAndType($month,$year,'cpi')
->with(array('product'=>function($query){ $query->select('id','name'); }))
->with(array('market'=>function($query){ $query->select('id','name'); }))->get();
but I am getting Trying to get property of non-object
There is nothing in your code snippet that would produce that error. However, I suspect you are getting the error when you are trying to access fields on the eager loaded product or market relationships without checking for their existence.
A common problem with specifying select statements and eager loading relationships is that the local and foreign keys usually get left out. However, these are the values that Laravel uses to match up all the related models, so they need to be selected, as well.
If price belongsTo a product and price belongsTo a market, then you also need to select the prices.product_id and prices.market_id fields. If price hasOne product or price hasOne market, then you'll need to select the prices.id field, and the corresponding foreign keys on the eager loaded relationships (products.price_id or markets.price_id).
Though, even once this is resolved, it is still a good idea to check to make sure the related record exists before trying to access it. In a hasOne/belongsTo relationship, if the related record doesn't exist, the relationship property will be NULL. If you try to access a field on NULL, you'll get the error you're seeing.

Resources