Using properly of eager loading - laravel

I have two tables: contracts and contractitems. I want to display all my Contract items and have a search for searching the contractor name.
Contracts
id
contract_code
contractor_name
ContractItems
id
contracts_id
item_name
class ContractItems extends Eloquent {
protected $table = 'ContractItems';
protected $guarded = [ 'id' ];
public $timestamps = false;
public function contract()
{
return $this->hasOne('Contracts', 'id', 'contracts_id');
}
}
$x = ContractItems::with(array('contract' => function($query){
$query->where('contractor_name', 'LIKE' , '%name%');
}))->take(1)->get();
I tried the code above but it is not displaying the correct data.

Related

Laravel Multiple Table Subquery

I'm using Laravel 6.0
I have 4 different tables.
Tables:
post_category
id
relation_post_id
post_type
category_id
photo_post
id
title
image
created_at
text_post
id
title
content
created_at
video_post
id
title
video_source_url
created_at
I'd like to list posts in two date ranges from the post_category table. For example
PostCategory::whereBetween('created_at',[$from, $to])->get();
The result should be:
Result
https://i.ibb.co/y53PmJ9/image.png
How can I do that?
Models:
PostCategory
class PostCategory extends Model
{
use SoftDeletes;
protected $table = 'post_category';
public $timestamps = true;
protected $fillable = [
'relation_post_id',
'post_type', // 1: text, 2: photo, 3: video
'category_id',
];
public function text()
{
return $this->belongsTo('App\TextPost','relation_post_id','id');
}
public function photo()
{
return $this->belongsTo('App\PhotoPost','relation_post_id','id');
}
public function video()
{
return $this->belongsTo('App\VideoPost','relation_post_id','id');
}}
TextPost
class TextPost extends Model
{
use SoftDeletes;
protected $table = 'text_post';
public $timestamps = true;
protected $fillable = [
'title',
'content',
];
}
PhotoPost
class PhotoPost extends Model
{
use SoftDeletes;
protected $table = 'photo_post';
public $timestamps = true;
protected $fillable = [
'title',
'image',
];
}
Video Post
class VideoPost extends Model
{
use SoftDeletes;
protected $table = 'video_post';
public $timestamps = true;
protected $fillable = [
'title',
'video_source_url',
];
}
Sure, it's possible. But since we just know your database design but not your codebase, it's hard to say. Intuitively I'd go with a polymorphic relationship.

passing datas with relationship in the view laravel

if i have this models relationship
Claims : this table hasMany(Refunds)
Refunds: with data of various request. this table belongsTo(Claims) AND belongsToMany(Services)
Services: with list of services. this table belongsToMany(Refunds)
Refunds-Services: bridge table for refunds and services
Claims model
class Claims extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'dossier',
'date_cla',
];
public function refunds()
{
return $this->hasMany(Refunds::class);
}
}
Refunds model
class Refunds extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'date_ref',
'status_ref',
];
public function services()
{
return $this->belongsToMany(Services::class)->withPivot(['services_id','services_amount','services_status']);
}
public function claims()
{
return $this->belongsTo(Claims::class,'claims_id');
}
}
Services model
class Services extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'code',
'name',
];
public function refunds()
{
return $this->belongsToMany(Refunds::class);
}
}
and in my controller this method
if ($request->ajax()) {
$dossier = request('dossier');
$claim = Claims::with('refunds')
->where('dossier', '=', $dossier)->first();
$
$view = view('pages.modify', compact('claim'));
$sections = $view->renderSections()['table'];
return $sections;
}
how can insert in the Controller the relationship between Refunds and Service to use the pivot (service_amount is in the Refunds-Services table)
<li>- {{ $item->pivot->services_amount }}</li>
Because now in the view cannot see this relationship
Thx
You can use Nested Eager Loading
$claim = Claims::with('refunds.services')
->where('dossier', '=', $dossier)->first();
As per the documentation:
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$books = App\Book::with('author.contacts')->get();

Laravel 6: Eager load relationships of returned models from query

I am building a tag filter. So far, I have a query that returns products who's tags or artists have been given to the query. I had to break it out since the if statements for the tag and author filters were a mess. The query is working and giving me all the results that I explicitly ask for in my select. But I need to get it to eager load each of the results relationships. I tried dropping a with('tags') into the mix, but it just assigns an empty collection. I am pretty sure I need the with('tags') method somewhere, I am not sure where. Or I could be entirely on the wrong track. I don't have to limit myself to just the tags relationship (a one-to-many relationship, so I can't include it in the query results).
Here is my snarl of a query, $tags and $artists are the lists of tags and artists.
if (count($tags)) {
$tagged_products = DB::table('product_tags')
->whereIn('product_tags.tag', $tags)
->groupBy('product_tags.product_uuid')
->select('product_tags.product_uuid')
->havingRaw('count(product_tags.tag) = '.count($tags));
} else {
$tagged_products = DB::table('product_tags')
->select('product_tags.product_uuid');
}
if (count($artists)) {
$artist_products = DB::table('profiles')
->whereIn('profiles.attribution', $artists)
->select('profiles.user_uuid');
} else {
$artist_products = DB::table('products')->select('products.user_uuid');
}
$results = Product::with('tags')
->join('profiles', 'products.user_uuid', '=', 'profiles.user_uuid')
->whereIn('products.uuid', $tagged_products)->whereIn('products.user_uuid',
$artist_products)->get();
$results->dd();
If I query a single Product record, I can get the values of the tags relationship just fine.
Here are models:
class Product extends Model
{
protected $fillable = [
'title', 'cost', 'description', 'thumbnail'
];
protected $primaryKey = 'uuid';
public $incrementing = FALSE;
public function tags(){
return $this->hasMany('App\ProductTag', 'product_uuid', 'uuid');
}
public function profile(){
return $this->hasOne('App\Profile', 'user_uuid', 'user_uuid');
}
}
class Profile extends Model
{
protected $fillable = [
'attribution', 'links', 'description', 'user_uuid',
];
protected $primaryKey = 'user_uuid';
public $incrementing = FALSE;
public function projects()
{
return $this->hasMany('App\Project', 'user_uuid', 'user_uuid');
}
}
class ProductTag extends Model
{
protected $fillable = [
'product_uuid', 'tag',
];
//
public function product()
{
return $this->belongsTo('App\Product', 'product_uuid', 'uuid');
}
}
You can easily query like this:
$results = Product::with(['tags' => function($query) use($tags){
if (count($tags)) {
$query = $query->whereIn('product_tags.tag', $tags)
->groupBy('product_tags.product_uuid')
->select('product_tags.product_uuid')
->havingRaw('count(product_tags.tag) = '.count($tags));
}
return $query;
}, 'profiles' => function($query) use($artists){
if (count($artists)) {
$query = $query->whereIn('profiles.attribution', $artists)
->select('profiles.user_uuid');
}
return $query
} ]);
And remember add 2 functions tags & profiles

laravel 5.7 correct way of getting results on many to many relation

I'm learning laravel framework and I've a pretty straightforward question:
I have three tables:
Foods table:
foods
--------------
id | name
Ingredients table:
ingredients
---------------
id, | name
Pivot table:
food_ingredient
---------------
food_id | ingredient_id
In the models I have the "belongsToMany" methods:
Food Model:
public function ingredients(){
return $this->belongsToMany('App\Models\Ingredient');
}
Ingredient Model:
public function foods(){
return $this->belongsToMany('App\Models\Food');
}
FoodsController (index):
$foods = Food::all();
foreach($foods as $food){
$food->ingredients = Ingredient::join('food_ingredient','food_ingredient.id','=','ingredients.id')
->where('food_ingredient.food_id',$food->id)->get();
}
I want to get the ingredients information (just the name until now) of each food, and this query (the one is in the foreach loop) does it, but I'm not sure if I'm doing it in a right way. I'm not using the belongsToMany relations so...there must be something wrong in my understanding.
How could I get the names of the ingredients?
Until know just those names are ok, but I'll add a third table "allergens" and it's pivot table "allergen_ingredient" soon. Then, I'll have to get each food, their ingredients, and also the allergens of each ingredient. So that, I want to do it well from now.
Thank you in advance.
Food Model
class Food extends Model
{
protected $table = 'foods';
protected $primaryKey = 'food_id';
public $incrementing = TRUE;
public $timestamps = FALSE;
protected $fillable = [
'food_name'
];
public
function ingredients()
{
return $this->belongsToMany(Ingredient::class, 'food_ingredients', 'food_id', 'ingredient_id');
}
}
Ingredient Model
class Ingredient extends Model
{
protected $table = 'ingredients';
protected $primaryKey = 'ingredient_id';
public $incrementing = TRUE;
public $timestamps = FALSE;
protected $fillable = [
'ingredient_name'
];
public
function foods()
{
return $this->belongsToMany(Food::class, 'food_ingredients', 'ingredient_id', 'food_id');
}
}
and you can call it this way:
$foods = Food::all();
foreach( $foods as $food )
{
foreach( $food->ingredients as $ingredient )
{
echo $ingredient->ingredient_name . " <br>";
}
}
food_ingredients is the pivot table name

Return count of relation along with parent data

Hello i have two tables in my database:
categories
events
I have a page that displays a list of all categories. However i want to display a count of how many events are in each category next to the category title.
eg.:
comedy (10)
music (5)
The relationship between these two models is one to many, as one category can have zero or more events.
My question is how do i fetch the total number of events for each category along with the category data when i execute this code:
$categories = Category::get();
What i have tried so far:
class Categories extends Model implements SluggableInterface
{
use SluggableTrait;
protected $sluggable = [
'build_from' => 'name',
'save_to' => 'slug',
'on_update' => true,
];
protected $table = 'categories';
public function events() {
return $this->hasMany('App\Models\Events', 'category_id');
}
public function eventsCountRelation() {
return $this->hasMany('App\Models\Events', 'category_id')->selectRaw('id, count(*) as count');
}
public function eventsCountAttribute() {
return $this->eventsCountRelation->count();
}
}
The error i get:
foreach($categories as $categoriy) {
echo $category->name.' ('.$category->events->count().')';
}
Returns something like:
comedy (10)
music (5)
If you want to print it in a view you don't need to load them in the controller.
But if you want to print it as json you need something like this:
$categories = Category::all();
In the Category Model you need to add this:
protected $appends = ['counter'];
public function getCounterAttribute() {
return $this->events->count();
}
Update your class like this:
class Categories extends Model implements SluggableInterface
{
use SluggableTrait;
protected $sluggable = [
'build_from' => 'name',
'save_to' => 'slug',
'on_update' => true,
];
protected $appends = [
'counter'
];
protected $table = 'categories';
public function events() {
return $this->hasMany('App\Models\Events', 'category_id');
}
public function eventsCounterAttribute() {
return $this->events->count();
}
}
You don't need more.

Resources