How to paginate objects from a relationship - laravel

How can i return this same query with pagination from the relacted produtos with categoria?
My Model DB:
Config Model Eloquent categoria:
namespace App\Models;
class Categoria extends ModelDefault
{
protected $table = 'categoria';
public function produtos()
{
return $this->belongsToMany('App\Models\Produto', 'categoria_produto', 'categoria_id')->withTimestamps();
}
}
Config Model Eloquent produto:
namespace App\Models;
class Produto extends ModelDefault
{
protected $table = 'produto';
public function categorias()
{
return $this->belongsToMany('App\Models\Categoria', 'categoria_produto', 'produto_id')->withTimestamps();
}
public function images()
{
return $this->hasMany('App\Models\ProdutoImagem','produto_id', 'id');
}
}
My query to get produtos from categoria:
$produtosPorCategoria = Categoria::with(['produtos.images.image'])
->where('slug', $categoria_slug)
->ativo()
->first();
dd($produtosPorCategoria);
Here you can see a printscreen from my returned array:

If I understood what you need. you should try this
$produtosPorCategoria = Categoria::with(['produtos.images.image'])
->where('slug', $categoria_slug)
->ativo()
->first();
Should be
$produtosPorCategoria = Categoria::with(['produtos.images.image'])
->where('slug', $categoria_slug)
->ativo()
->first();
$produtosPorCategoria = $produtosPorCategoria->produtos()->paginate(5);

Related

laravel filter on relationship

hi i have this relationships with these 3 models
Customers
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Customers extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'contr_nom',
'contr_cog',
'benef_nom',
'benef_cog',
'email',
'polizza',
'targa',
'iban',
'int_iban',
'cliente',
];
public function claims()
{
return $this->hasMany(Claims::class);
}
public function refunds()
{
return $this->hasManyThrough(Refunds::class, Claims::class);
}
}
Claims
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Claims extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'dossier',
'date_cla',
];
public function refunds()
{
return $this->hasMany(Refunds::class);
}
public function customers()
{
return $this->belongsTo(Customers::class,'customers_id');
}
}
and Refunds
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Refunds extends Model
{
public $primaryKey = 'id';
protected $fillable = [
'date_ref',
'status_ref',
'disactive',
];
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');
}
}
i have this in the controller (part of the code)
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))->get();
it works, i can get customers information (parent table) for each dossier ( i put in a datatables)
But i cannot insert another filter based on Refunds table.
I need to show only dossiers where
['status_ref', '>',4]
the problem is that status_ref is in Refunds table
i tried to do somthing like this but no works
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))->refunds()
->where('status_ref', '>',4)
->get();
I cannot understand why....
Thx
You have to use whereHas like:
$data = Claims::with(array('customers'=>function($query){
$query->select('id','contr_nom','contr_cog','targa','email','gcliente');
}))
->whereHas('refunds', function (Builder $query) {
$query->where('status_ref', '>', 4);
})
->get();

Laravel 5.5 Relationships

I'm trying to implement relationships between models and i recieve "Trying to get property 'products' of non-object" and i don't understand why, because i used this before in the same way and it's worked fine.
The logic of relationship is that 1 Merchant hasMany Products
this is the code that i'm using:
Merchant Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Merchant extends Model {
protected $table = "merchants";
protected $fillable = [
'merchant_id', 'merchant_name', 'secret_key', 'merchant_address', 'merchant_phone', 'merchant_admin',
'merchant_contact', 'merchant_mail', 'merchant_description', 'enable', 'created_at', 'updated_at'];
public function users() {
//many to many
return $this->belongsToMany('App\User');
}
public function branchOffices() {
return $this->hasMany('App\BranchOffice', 'merchant_id', 'merchant_id');
}
public function products() {
return $this->hasMany('App\Products', 'merchant_id', 'merchant_id');
}
public function transactions() {
return $this->hasMany('App\Transaction', 'merchant_id', 'merchant_id');
}
public function readers() {
return $this->hasMany('App\Reader', 'merchant_id', 'merchant_id');
}
}
Product Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model {
protected $table = "products";
protected $fillable = [
'id', 'barcode', 'description', 'price', 'currency_id', 'merchant_id', 'branch_id',
'enable', 'created_at', 'updated_at'];
public function merchants() {
return $this->belongsTo('App\Merchant', 'merchant_id', 'merchant_id');
}
public function currencies() {
return $this->belongsTo('App\Currency', 'iso_4712', 'currency_id');
}
public function branch_sectors() {
return $this->belongsToMany('App\BranchSector');
}
}
And this is the method in ProductController:
public function merchantProducts() {
$products = Merchant::find('merchant_id')->products;
return $products;
}
If someone can help me i'll be very thankfull.
Thanks in advance!!
Assume merchant is not guaranteed existing in database giving merchant id, it is better off to check if merchant exists, and retrieves its products if so.
$products = collect();
$merchant = Merchant::find($merchant_id);
if($merchant) {
$products = $merchant->products;
}
return $products;
all!!
Finally i solved this problem using resources in this way:
public function merchantProducts(Request $request) {
$merchant_id = $request->merchant_id;
$products = Product::where('merchant_id', $merchant_id)->paginate(15);
return ProductResource::collection($products);
}
Thanks to all!!

How to filter my data in laravel 5.4?

I have 3 tables:
products
productcolors
productbrands
The relationships between them are:
a product has many productcolors;
productbrands belong to a product.
All products are tagged with this dependency: cviebrock/eloquent-taggable.
I have used this to render all swim tagged data:
$allproducts = Product::withAllTags('swim')->get();
Now, I want to filter data with colors and brands, but I don't know how to do that.
Here is my product model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentTaggable\Taggable;
use Carbon\Carbon;
class Product extends Model
{
use Taggable;
protected $table ='products';
protected $dates = ['published_at'];
public function setPublishedAtAttribute($date) {
$this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d', $date);
}
public function scopePublished($query) {
$query->where('published_at', '<=', Carbon::now());
}
public function scopeUnpublished($query) {
$query->where('published_at', '>', Carbon::now());
}
public function scopeNewin($query) {
$query->where('published_at', '>', Carbon::now()->subDays(7));
}
public function getCreatedAtAttribute($date) {
return $this->asDateTime($date)->toFormattedDateString();
}
public function getproductcolor() {
return $this->hasMany('App\productcolor');
}
public function getproductimage() {
return $this->hasMany('App\productimage');
}
public function getproductbrand() {
return $this->hasMany('App\productbrand');
}
public function getproductsize() {
return $this->hasMany('App\size');
}
}
Here is my productcolor model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentTaggable\Taggable;
class productcolor extends Model
{
use Taggable;
public function getproductcolor() {
return $this->belongsTo('App\Product');
}
}
Here is my productBrands model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentTaggable\Taggable;
class productbrand extends Model
{
use Taggable;
public function productBrand() {
return $this->belongsTo('App\Product');
}
}
Use whereHas and orWhereHas
$allproducts = Product::whereHas('productColors', function($query) {
$query->where('column', 'condition', 'value');
})->withAllTags('swim')->get();
Try this:
$allproducts = Product::withAllTags('swim')->with(['getproductcolor' => function ($productColorQuery) {
$productColorQuery->where('blah', '=', 'blah');
}, 'getproductbrand' => function ($productBrandQuery) => {
$productBrandQuery->where('blah', '=', 'blah');
}])->get();
Use whereHas():
Product::whereHas('colors', function ($q) use ($colorName) {
$q->where('name', $colorName);
})
whereHas('brands', function ($q) use ($brandName) {
$q->where('name', $brandName);
})
->withAllTags('swim')
->get();
Don't forget to define relationships in the Product model:
public function colors()
{
return $this->hasMany(Color::class);
}
public function brands()
{
return $this->hasMany(Brand::class);
}

Laravel scout check if relation is not empty?

namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Event extends Model
{
protected $table = 'events';
public $timestamps = true;
use Searchable;
use SoftDeletes;
protected $dates = ['deleted_at'];
public function entities()
{
return $this->belongsTo('App\Entity', 'entity_id');
}
public function users()
{
return $this->belongsTo('App\User', 'id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'id');
}
public function toSearchableArray()
{
$data = $this->toArray();
$data['entities'] = $this->entities->toArray();
return $data;
}
}
This is my model for Event, as you can see I am using toSearchableArray which is Laravel scout function to import 'relations' to algolia. However the problem is that sometimes it is empty. So for example
event id 1 has entity_id 1
but in another example
event id 2 has entity_id = null
How can I modify this function to check if the entities() relation is not empty before putting it into array?
if i understand u correctly this should help. if the relationship does not exist return an empty array and scout won't update the index
public function toSearchableArray()
{
if(is_null($this->entities)){
return [];
}
$this->entities
return $this->toArray();
}
please update foreign_key in relation as this
user_id as foreign_key instead of id
event_id as foreign_key instead of id
public function users()
{
return $this->belongsTo('App\User', 'user_id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'event_id');
}
I think if load the relation before the toArray().
public function toSearchableArray()
{
$this->entities;
return $this->toArray();
}

Subrelationships not using previous conditions

I'm using Laravel 4. I have the following models:
class User extends Eloquent {
protected $table = 'users';
public function questions()
{
return $this->hasMany('UserQuestion', 'user_id', 'user_id');
}
}
class UserQuestion extends Eloquent {
protected $table = 'user_questions';
public function user()
{
return $this->belongsTo('User', 'user_id', 'user_id');
}
public function subquestions()
{
return $this->hasMany('UserSubquestion', 'question_id', 'id');
}
}
class UserSubquestion extends Eloquent {
protected $table = 'user_subquestions';
public function question()
{
return $this->belongsTo('UserQuestion', 'question_id');
}
public function answers()
{
return $this->hasMany('UserAnswer', 'subquestion_id', 'id');
}
}
class UserAnswer extends Eloquent {
protected $table = 'user_answers';
public function subquestion()
{
return $this->belongsTo('UserSubquestion', 'subquestion_id');
}
}
I have the following query:
$results = User::with(['questions' => function($query) {
$query->where('status', '1');
$query->where('category', 'medicine');
}])
->with('questions.subquestions', 'questions.subquestions.answers')
->get();
However, the where conditions I'm applying to the questions relationship aren't being applied to the joined tables (subquestions and answers).
How can I make the conditions apply to them as well?
Note: The values of status and category in the conditions are dynamic (i.e. won't always be 1 or medicine).
Try doing your call like this instead:
$results = User::with(['questions' => function($query) {
$query->where('status', '1');
$query->where('category', 'medicine');
},
'questions.subquestions',
'questions.subquestions.answers'
])->get();
Note, this time the method with is only called once.

Resources