Checking value of a related model in Laravel - laravel

I have users. Users have a relationship with a country, and country has a region.
I would like to access all users who are within a region, and I am doing it through their related country, like this:
user->country->region
When I tried to use whereHas, like this:
$users = User::whereHas('country', function ($query) {
$query->where('region', 3);
})
->get();
I got an error that said there was an unexpected } on the 3rd line. I would like to know what is the best method of doing this.

Use Laravel Eloquent relationship, In Laravel eloqunent there are Has Many Through option available for as per your requirement.
Please check this :-> Here is laravel documentation link

Related

Laravel: Ordering posts by category in numerical order

In my application I want to order my posts by category in numerical order.
So I guess I need a mapping table like this:
category_id | post_id | sort_order
then setting up a kind of "Order model" with specific methods that handle it all and use this model as a relationship with the Post model.
But before I start on this project I'd like to know if there is not a Laravel package out there that does the job or another solution that I might have missed.
I'm not 100% sure, if I understand your need correctly, but I guess your posts are stored in a DB.
Then you can simply directly get the posts from DB ordered:
$posts = DB::table('posts')
->orderBy('category_id ', 'asc')
->orderBy('post_id', 'asc')
->get();
See the documentation:
https://laravel.com/docs/8.x/queries#ordering-grouping-limit-and-offset
I don't think, you need a Order model or something similar to realize this.

How do the "has" and "whereHas" methods work in Eloquent?

I have a relationship defined between users and permisson, a user can have many permissions.
When I use "with" I get the data normally.
$user->with('permisson')->get();
I get the user with their permissions.
When I use "has" it only returns the user.
$user->has('permission')->get();
For what I've read, I should get the permissons if the user contains at least one permission.
I am using Postgres driver.
with is used for eager loading a relationship. You'd use it to fetch all of the specified relationships for each model (individually, or in a collection).
has is for using the relationship as a constraint or filter. As you said, using something like has('permission') will add a constraint to the query that says "only get Users that have at least one permission". This does not automatically load the relations like with(), it only creates the constraint.
You can combine the two if you want to take advantage of both the constraint and eager loading the results.
User::has('permission')->with('permission')->get();
Seems a bit redundant, I know.
From laravel docs:
If you wish to limit your results based on the existence of a relationship, you should use the has method. For example, if you want to retrieve all blog posts taht have at least one comment, yo may pass the name of the relationship to the has and orHas methods:
$posts = Post::has('comments')->get();
So, when you use the has method, it will not return the relationship, but just the post models which has at least one comment.
The whereHas and orWhereHas methods allows you to add customized constraints to a relationship constraint, such as checking the content of a comment (using the laravel example):
$posts = App\Post::whereHas('comments', function (Builder $query) {
$query->where('content', 'like', 'foo%');
})->get();
When you use the with method, you are loading the realtionship with the model:
$user->with('permission')->get()
This code will load the user and the permission relationship, while this one
$user->has('permission')->get();
will load the user who has some permission.
Hope it helps.

Retrieve selected keys from database from relations

I am using laravel 4 and I have to retrieve registrations and all users associated with that registrations but user table has lot more keys but I only need 3 keys so how can I get selected keys. I know laravel provide select method but its not working on relations.
Registration::where('section_id', '=', $key->id)
->with('user')
->select('users.id', 'users.name')
->get();
I tried users and user but nothing works. Could someone please post correct way to load this query.
Edit:
- Registration has one user
- Registrations has one section
I have registration table that contains section id and user id. I want to get all users, signed up for particular section. So this is very simple query and its working fine only problem is retrieving selected keys from database.
In your Registration model change your relation to this
public function user()
{
return $this->hasOne('User')->select('id','name');
}
And in your controller write this
Registration::where('section_id', '=', $key->id)->with('user')->get();
Hope this work for you.

Laravel passing variable from multiple models

I have 2 models
User
Customer
Each user hasMany customers (aka Accounts)
the user model has
public function customer() {
return $this->hasMany('App\Customer', 'id','customer_id');
}
but when i try to output this:
$user->customer->name
i get an error saying:
Undefined property: Illuminate\Database\Eloquent\Collection::$name
When i use this one, i get the entire customers record output in JSON.
$user->customer
So the relationship is working, but obviously i am missing something. I was sure this was the right way to do it. I swear this worked in Laravel4.2 but now that I'm in Laravel 5 it doesn't.
As the error and the below link says, It is returning a collection (hasMany) not a single object, you need to either loop over the collection or do direct access in the collection based on the index.
that is to say... does doing this work?..
$user->customer[0]->name
http://laravel.io/forum/04-10-2014-undefined-property-illuminatedatabaseeloquentcollectionitem
You should loop over customers, if you want display customers in laravel view you can do the following
#foreach
($user->customer as $cust)
{{$cust->name}}
#endforeach

laravel eloquent get related articles based on a tag

I'm a bit confused about how to do the following.
I have a table of articles and a table of tags with a many to many join and a pivot table between the two. I've got the relationships set up in the models
An articles can have more than one tag.
How can I easily(?) obtain a list of related articles for an article based on the tags attached to the current article.
I've tried querying from the tags side as follows:
foreach($article->tags()->get() as $tag) {
$relatedArticles .= Tag::with('articles')
->where('id','=', $tag->id)
->take(6)
->get();
}
This produces a nil response
I'm not sure about how to query from the articles to find articles with the tags dynamically.
So if an article has attached tag1 and tag2 I then want to retrieve all articles which have either tag1 or tag2 attached to them (ideally sorted on article date). The tags will be different for each article and may just be one or many.
Ideally i'd like to do this with an eloquent query but not essential - I'm not sure how to do in mysql either as a starting point.
Any help appreciated
Provided you are using Laravel 4.1, you can do something like this using the whereHas eloquent method:
$tag_ids = $article->tags()->lists('id');
$relatedArticles = Article::whereHas('tags', function($q) use ($tag_ids) {
$q->whereIn('id', $tag_ids);
})
->orderBy('created_at')
->take(6)
->get();
Breakdown
There's a few things going on here:
lists()
You can use the lists method on a select to get just a particular column, we're only concerned with the ID column in this case.
More info here: http://laravel.com/docs/queries#selects
whereHas()
We're using the new whereHas method which you can read.
More more about here: http://laravel.com/docs/eloquent#querying-relations
use()
Since the whereHas method accepts a closure (or 'anonymous function'), the function doesn't have any access to variables set externally, so we need to send them through to the function. We can do this with use.
More information here: http://www.php.net/manual/en/functions.anonymous.php

Resources