In laravel, is there a way to get the list of objects that belong to two models?
For example,
Model transactions:
belongs to users
belongs to category
Model user:
has many transactions
Model category:
has many transactions
Assuming these relationships are correctly defined, what kind of query would you make in, say the controller, to access the set of transactions that belongs to user x and category y?
Assuming that your Transaction table has the foreign keys for user_id and category_id, you could do:
$transactions = Transaction::where('user_id', '=', 'x')
->where('category_id ', '=', 'y')
->get();
Related
I'm working on a Laravel installation where I have (among other things)
Teachers (table:users (cols: id, name, type), model:User, users.type = 2)
Students (table:users (id, name, type), model:User, users.type = 1)
Schools (table:schools (id, name), model:School)
Collections of students (table:student_collection (id, name), model:StudentCollection)
& table student_collections_users for linking the student-users to collections (model: StudentsCollections, columns id, user_id, collection_id)
I have managed to setup some relationships, but can't get my head around to get
Which teachers teach a student
Which collections does a student belong to
Currently I'm trying to get the collections with
//User.php
public function collections() {
$collection = $this->hasManyThrough('\App\StudentsCollections', '\App\User', 'id', 'user_id');
return $collection;
}
//Controller
$user = \App\User::find($id);
$user->collections = $user->collections();
but it only returns the id's of the collections. How can I get the full data object for each collection?
I'm using Laravel 5.3.
First, In your example code, are the table names correct?
I see a table called 'students_collections', but your belongsToMany has a table name (second param) 'student_collections_users'. That's a typo, I presume.
Second, what does return an empty result? Calling the collections method or the collections property on the User model? Can you add some sample code?
Third: you have actual data in the database (through a seeder or real data)? I know this is obvious, but sometimes people tend to forget the obvious... :-)
Let's say I have three models with this relationsship
USER
hasMany (app/organisation)
ORGANISATION
hasMany (app/order)
ORDER
For one level I could just go
user->organisations()->get()
And get all the organisations tied to the user. But every organisation also have 0..many ORDER entities. So I want to do this:
user->organisations()->orders()->get()
To get a list of all the orders from all the organisations from a certain user. Is that possible this way?
What you can simply do is implement hasManyThrough() relationship on User model.
public function orders()
{
return $this->hasManyThrough(Order::class, organisation::class);
}
then you can query like,
$user->orders()->get();
I have three Models (Organization, User, Visit) and 4 tables (organizations, users, organization_user, visits). I'm trying to get the accumulative total of user visits for an Organization.
Organization
------------
id,
name
User
---------
id,
name
Organization_User
----------------
id,
organization_id,
user_id
Visit
--------------
id,
user_id
views
Just to clarify, there is no Organization_User model, that is just the pivot table used by User and Organization:
$organization->belongsToMany('User');
$user->belongsToMany('Organization');
I could query all the user_ids from the pivot table by group_id, and then get all the visits for each user_id, but what's the more Eloquent approach?
A User hasMany Visits and a Visit belongsTo a User. A Visit doesn't belong to an Organization.
Solved it by using whereIn(). Basically with no change to my current relationship setup...to get accumulative views I did this:
$org = Organization::find($org_id);
return DB::table('visits')->whereIn('user_id', $org->users->modelKeys())->sum("views");
The modelKeys() returns all the user ids tied to that Organization. Then I get the sum of all the views for those users.
*Note it's also important to use Organization::find and not DB::table('organization') in order to maintain the Eloquent relationship. Otherwise $organization->users will give an error.
I think you might want a 'Has Many Through' relationship like so:
class Organization extends Model
{
public function visits()
{
return $this->hasManyThrough('App\Visit', 'App\User');
}
}
Then you could call count().
Laravel 5.1 doc
I have three database tables in my application. As an example, here is what I have now:
items TABLE: id, quantity, price, month_id (FK), department_id (FK)
months TABLE: id, month
department TABLE: id, department
I have already defined hasMany and belongsTo relations on the models. With these relations, I'm able to perform the query App\Month::first()->items to retrieve all first month items. However, if I want to query on both month and department, what is the best way to do it in this case?
I can certainly do it like this:
$month = App\Month::first();
$month->items()->where('department_id', '3')->get();
Is there more elegant way of doing this query?
First of all you can tell Eloquent to eagerly load needed relations to get better performance. You can do this by using with() method and defiling all needed relations - see http://laravel.com/docs/5.0/eloquent#eager-loading for more details.
Moreover, if you want to apply some additional criteria on loaded relations, you can do so using the same with method, but using different syntax to define relations and criteria:
$users = User::with(['posts' => function($query)
{
$query->where('title', 'like', '%first%');
}])->get();
I have a many-to-many relationship with models Competition and Season with a pivot table named competition_season.
Season->belongsToMany->Competitions->hasMany->Teams->hasMany->Players
I want to query the data of all players in a team in a specific season.
something like
\App\Player::with('team.competition.season')->where('team.competition.season.id', 2);
However since season is a collection (competition has many seasons) at this moment i can never query it like this.
Can someone point me in the right direction to properly select all players in a team in a particular season?
First, you need to add relation hasManyTrough at your model (read more about at: has-many-through)
Then, all you need is "whereHas"
$players = \App\Player::with('season')->whereHas('season', function($q){
$q->where('season.id', '=', 2);
})->get();