Laravel eloquent has hasmany of hasmany - php

How to show all company who has photo attachment?
company:
id | name
user:
id | name | company_id
post:
id | user_id | text
post_attachment:
id | post_id | path | type
company model:
public function users() {
return $this->hasMany('App\User')->orderBy('id', 'ASC');
}
user model:
public function posts() {
return $this->hasMany('App\Post');
}
posts model:
public function images(){
return $this->hasMany('App\PostsAttachment')->where("type", "image");
}
I want to get all company who have user(s) that have post(s) with minimal 2 images attachment. Anyone can help me?
I tried Company::has('users.posts.images', '<', 2)->get(); but it also give companies who has user image below 2.

Using eloquent you could write your logic as
$companies = Company::has('users.posts.images')->get();
See Querying Relationship Existence

Related

Laravel Relationship with integer[] type of postgresql column

I have categories table and products table. in products table have category_id column type of integer[].
ex: {1,2,3}
.
And I need products list with category relation which categories.id exist products.category_id
I tried in model Product:
public function category()
{
return $this->belongsTo(Category::class, \DB::raw("ANY(category_id)"), 'id');
}
no get category is null.
you should use belongs to many relation.
because integer[] type is for saving arrays of ints.
try to set it in your model like this:
in your Product(model) you will get this relation method:
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class);
}
And in your Category(model):
public function products(): BelongsToMany
{
return $this->belongsToMany(Product::class);
}
Refrence
You can try this using laravel query builder
public function category()
{
return DB::table('products')
->join('categories', 'products.category_id', '=', 'categories.id')
->get();
}
First of all, I dont think it's possible to do this with the Laravel Relationship Methods.
Second of all, if you are using Postgres, which is a relational Database, you should definitely read up on the fundamentals of database normalization.
I would recommend you have a so called pivot table, that links your products to your categories, which could look something like this:
Disclaimer: You dont need to create a Model for this. Just make a migration with php artisan make:migration create_categories_products_table
categories_products
| id | category_id | product_id |
|---------------------|------------------|---------------------|
| 55 | 1 | 5 |
| 56 | 2 | 5 |
| 57 | 3 | 5 |
| 58 | 1 | 6 |
This table links your tables and this is much more easy to handle than some arrays stored as json.. maybe think about it, it is not that much work to do. You can read upon it on the Laravel Documentation or try searching on google for pivot tables and normalization.
When you have done that:
Now you can just use the Laravel belongsToMany Relationship like so:
// Product.php
public function categories()
{
return $this->belongsToMany(Category::class, 'categories_products');
}
// Category.php
public function products()
{
return $this->belongsToMany(Product::class, 'categories_products');
}
I can't relation but with attribute i can get categories
firstly cast category_id to array and
public function getCategoriesAttribute()
{
return Category::whereIn('id',$this->category_id)->get();
}
and it works

Attaching extra model to BelongstoMany relations

I have two tables (users and drinks) with a pivot table, the user has a hasOne relation with profiles table, is there a way to attach the profile table to the pivot table and get all data.
Table user
id | name | email
Table profile
id | user_id | picture
Table drinks
id | name | price
Pivot Table user_drinks
id | user_id | drink_id | quantity | price | status
Drink Model
public function users()
{
return $this->belongsToMany('App\User', 'user_drinks', 'drink_id', 'user_id')->withPivot('price', 'quantity')->withTimestamps();
}
User Model
public function drinks()
{
return $this->belongsToMany('App\Drink', 'user_drinks', 'drink_id', 'user_id')->withPivot('price', 'quantity')->withTimestamps();
}
public function profile() {
return $this->hasOne('App\Profile');
}
PS: I don't wanna write this with raw sql query, it's driving me nuts.
I wouldn't change the tables relation.
I'd use the ->with() function to get the profile information within the existing relations.
So $user->drinks()->where('drink_id', $drink_id)->with('profile')->get(); would be my guess.

Lumen/Laravel many-to-many (fetch data in the middle)

I am testing out Lumen here and have a question regarding many-to-many relationship.
I've read the documentation, but I've either overlooked the answer or I might be dumber then I think. Also have to add that I am pretty new to the MVC pattern.
So I have an example here where we can have many permissions, many users and each user can have many permissions.
I have 3 database tables:
-------------------------------------
| users | id | firstname | lastname |
-------------------------------------
----------------------------------------------------------------
| permissions_users | id | permission_id | user_id | from | to |
----------------------------------------------------------------
----------------------------------
| permissions | id | name | desc |
----------------------------------
And for now I've created 2 models:
User:
public function permissions(){
return $this->belongsToMany('App\Permission', 'permissions_users', 'user_id', 'permission_id');
}
Permission:
public function users(){
return $this->belongsToMany('App\User', 'permissions_users', 'permission_id', 'user_id');
}
Now my question is, what if I want to fetch the "from" and "to" dates in the permissions_users table, what do I do?
Do I create a model called PermissionUser "between" that act as a middleman between User and Permission or is there another way?
Thanks
You can define these attributes also in select on relation. I think this will work for you.
public function permissions()
{
return $this->belongsToMany('App\Permission', 'permissions_users', 'user_id', 'permission_id')->select(['from', 'to']);
}
You might need to add permission columns too in select else it might show only from and to in your relation object.
public function permissions()
{
return $this
->belongsToMany('App\Permission', 'permissions_users', 'user_id', 'permission_id')
->withPivot('from', 'to');
}
foreach($user->permissions as $permission){
$permission->pivot->from;
$permission->pivot->to;
}

Laravel variable model polymorphic

I have a table as follows in my database:
table area_blocks;
id
owner_type
owner_id
created_at
updated_at
in the owner_type field it has the Eloquent Model name and the owner_id is the id of that model in the database. Example:
db: area_blocks
id | owner_type | owner_id
1 | App\Models\Title | 3
2 | App\Models\Title | 4
3 | App\Models\Textarea | 1
So I'm expecting when I fetch all of these to also eager load the relevant field from the eloquent model stored in owner_type.
Is there an eloquent relationship that can bring back that record from the owner_type field using eager loading? I've tried $this->morphTo(), e.g.
public function block()
{
return $this->morphTo();
}
but that is returned as null. Any ideas how this can be done?
Example code;
<?php
namespace App\Models;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;
class AreaBlocks extends Model
{
protected $with = ['block'];
public function block()
{
return $this->morphTo();
}
}
Route::get('/', function(){
return App\Models\AreaBlocks::all();
});
You have to specify the column name/prefix:
public function block()
{
return $this->morphTo('owner');
}
Or rename the relationship:
public function owner()
{
return $this->morphTo();
}

Laravel 5.4 | Fetching data from Pivot Table

I have 4 tables in my database:
Table 1: Category
---|------
id | name
---|------
1 | Cars
In 'Category' model class I have defined the following relationship:
class Category {
public function fields() {
return $this->belongsToMany('App\Field');
}
}
Table 2: Field
id | name
---|-------
1 | Make
In 'Field' model class I have defined the following relationship:
class Field {
public function categories() {
return $this->belongsToMany('App\Category');
}
}
Table 3: Field_Options
field_id | value
---------|-------
1 | Audi
1 | BMW
In 'FieldOption' model class I have defined the following relationship:
class FieldOption extends Model
{
public function field() {
return $this->belongsTo('App\Field');
}
}
Table 4: Category_Field
category_id | field_id
------------|-------
1 | 1
Now I need to fetch all the fields and field_options for category_id=1. How can I achieve this using Laravel?
Thanks!
First define relationship between Field and FieldOptions
public function options() {
return $this->hasMany('App\FieldOption');
}
Then you can eager load all relationships like this
$category = Category::with('fields.options')->find(1);
//Get category 1, with all fields and their respectif fieldOptions

Categories