Getting data from pivot table using eloquent - laravel

I have two tables with a pivot table
Table user
id | name | email
Table drinks
id | name
Pivot Table user_drinks
id | user_id | drink_id | quantity | price | status
I want to get all users and drinks with status set to 1 and their latest details from the pivot table, that is use the user_Id to get the username and drink_Id to get the drink name then the price and quantity from the pivot table.

In your User Model put this //App\User.php
public function drinks()
{
return $this->belongsToMany(Drink::class)->where('status',1);
}
In your DrinkModel put this //App\Drink.php
public function users()
{
return $this->belongsToMany(Drink::class)->where('status',1);
}
Then in your controller you can use this like
$users = User::has('drinks')->get(); //to get all the user that has drinks column status set to 1
foreach ($users as $user) {
//you rest of code
}

Related

Laravel relationship filter by company_id

I am doing a laravel api with custom permissions feature.
This is my structure of tables:
User
id | email | password
Company
id | companyName
Permissions
id | name
User_has_permissions
user_id | company_id | permission_id
I am get the user and permissions with code below in model:
public function permissions() {
return $this->belongsToMany(Permission::class, 'user_has_permission', 'user_id', 'permission_id');
}
And in controller:
public function show($company_id, $user_id) {
//now I need return only permissions related with $company_id
return User::with(['permissions'])->find($User_id);
}
Now, I am need get the user and your permissions, but, only related by company_id.
Anyone have any idea how can I get this result?
Any idea is welcome.
Thanks a lot.
You can query with includes, by doing key value syntax as the parameter. In BelongsToMany, it inner joins with the pivot table, which would make it possible to add a condition on the comapny_id.
return User::with(['permissions' => function ($query) use ($company) {
$query->where('user_has_permission.company_id', $company->id);
}])->find($id);

Joining pivot table to access data

I am trying to access data from a database query which I think will need a join. I have users that can be apart of many groups. I am using a belongsToMany
relationship. My Models are like so
class User extends Model
{
protected $table = 'users';
protected $guarded = [];
public function group()
{
return $this->belongsToMany('App\Group', 'users_user_groups')->withPivot('user_id', 'group_id');
}
}
class Group extends Model
{
protected $table = 'user_groups';
protected $guarded = [];
use SoftDeletes;
public function user()
{
return $this->belongsToMany('App\User', 'users_user_groups')->withPivot('user_id', 'group_id');
}
}
When I run everything I need too, I might get data like the following.
users
+----+---------------+
| id | name |
+----+---------------+
| 1 | John Doe |
+----+---------------+
user_groups
+----+---------------+-----------------+
| id | name | description |
+----+---------------+-----------------+
| 1 | Group AA | Something |
+----+---------------+-----------------+
| 2 | Group BB | Something |
+----+---------------+-----------------+
users_user_groups
+----+---------------+-----------------+
| id | user_id | group_id |
+----+---------------+-----------------+
| 1 | 1 | 1 |
+----+---------------+-----------------+
| 2 | 1 | 2 |
+----+---------------+-----------------+
So I know user with the id 1 belongs to the user_groups with ids of 1 and 2. What I am trying to do is grab all the users within my database who
belong to a user_group with the name admin. So I am trying something like this
DB::table('users')->select('userName')
->join('user_groups', 'users_user_groups')
->where('name', '=', 'admin')->get();
This I know is all wrong, how can I get all users within a group when using belongsToMany and a pivot table?
Thanks
Eloquent uses relations, not the query builder.
You can achieve what you're aiming for by doing something like this:
$group = Group::where('name', 'admin')->first();
$users = $group->users; // Where users is the name of your relationship (At the moment you have user)
Under the hood that will do two SQL statements and map them together in eloquent objects, rather than a join. The statements will look something like this:
select * from user_groups where name = ? and deleted_at is not null limit 1
select * from users where id in (?, ?)
When you have an instance Group you execute the relationship by calling it as if it was a property. So after that $users will contain a collection of User instances, so you can just loop through them:
foreach ($users as $user) {
// Do something with $user
}

Categories and Sub Categories Query?

Im trying to set up a database so that I can query it and get all products out for a category and query it for a particular sub category.
I have a products table
id | title | category_id (fk)
And a categories table:
id | title | parent
So if the categories looked like this:
id | title | parent
1 | books | null
2 | crime | 1
3 | spy | 2
4 | dvd | null
5 | cd | null
And products:
id | title | category_id (fk)
1 | 007 | 3
1 | Murder| 2
A product would belong to one category. Above the '007' product belongs to the 'Spy' sub category. 'Murder' belongs to the 'Crime' sub category. Both belong to the parent 'books' category.
How would I query the database to:
Get all products for a sub category (in example for spy I would get '007')
Get all products for a parent category, so if I want all products for books I would get both '007' and 'Murder'.
You can just find all subcategories of a parent category and then use that to fetch the associated products. The solution below assumes you have Eloquent Models for each table you described, so a Categoryand a Product model.
The Product model doesn't require any additional code, it just needs to exist. The Category model will have to look as follows:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function products()
{
// Build an array containing the parent category ID and all subcategory IDs found
$categoryIds = array_merge([$this->id], $this->subcategoryIds());
// Find all products that match the retrieved category IDs
return Product::whereIn('category_id', $categoryIds)->get();
}
protected function subcategoryIds($id = null, &$ids= [])
{
// If no ID is passed, set the current model ID as the parent
if (is_null($id)) {
$id = $this->id;
}
// Find subcategory IDs
$categoryIds = $this->query()->where('parent', $id)->lists('id');
// Add each ID to the list and recursively find other subcategory IDs
foreach ($categoryIds as $categoryId) {
$ids[] = $categoryId;
$ids += $this->subcategoryIds($categoryId, $ids);
}
return $ids;
}
}
Now to find the products within the Books category, you just need to find it by id and call the products method on the model:
$products = App\Category::find(1)->products();

Laravel 5 get name based on ID

I have a users and departments table. So my departments table might have a row like so
id | departmentName
----------------------
2 | Marketing
----------------------
And the users table might have something like
id | name | email | departmentId
-------------------------------------------------------
18 | Nick | nick#email.com | 2
-------------------------------------------------------
So the users table links to the departments table via the id.
So now onto my UserController, in the index function, I do
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}
Now that will display everything within my users table.
My problem is, I do not want to display the departmentId. I want to display the departmentName which is linked to that departmentID. So in the above example, my users index page for that one row should show Marketing, not 2.
How would I go about doing this?
Thanks
You can use Eloquent Relationships. What you described in your question is a One-to-Many Relation, meaning a department can have many users, and each user belongs to a department. So you'll need to setup a model for your departments table (if you haven't done so already) and then define the relationship in your User model like so:
class User extends Model
{
public function department()
{
return $this->belongsTo('App\Department', 'departmentId');
}
}
You can then access the department details in your view via that relationship:
#foreach ($users as $user)
{{ $user->department->departmentName }}
#endforeach

Laravel Eloquent - many to many with where for the pivot table

I'm trying to see what the best way to do the following.
I have 3 tables: users, items and item_user.
users and items table are pretty generic, id and a few columns to hold whatever data.
item_user table has the following structure
id
item_id
user_id
user_type [ 1 - Owner | 2 - Follower | 3 - Something else ]
Relationships:
Each Item has 1 Owner (user type)
Each Item has many followers
Each User can own many Items
Each User can follow many Items
I would like to have the Owner and Followers be the Users table so I don't need to replicate user data. I created a pivot table of item_id, user_id and user_type to hold these relationships.
So the question is how to I do this in Laravel Eloquent?
Item Model looks like:
public function user() {
return $this->belongsToMany('Users');
// This isn't actually correct since it belongs to only one User but not sure how to specify a where user_type = 1;
// return $this->belongsTo('User');
}
User Model looks like:
public function item() {
return $this->hasMany('Item');
}
Thanks!
You can just append the condition to your belongsToMany declaration:
public function user() {
return $this->belongsToMany('Users')->where('user_type', 1);
}
This will return only the User entries that have user_type = 1 in your pivot table. And just to make it more clear you could name the method owner() instead of user() to reflect the added condition.

Resources