create index for following LARAVEL eloquent query - php

Hi I have more than 500k records in items table Its takes more than 9 seconds to execute this query ineed to make it milliseconds to execute this query using mysql index
$products = \App\items::with([
'item_store' => function($query) {
$query->select('size', 'item_id', 'item_store_id');
},
'pics' => function($query) {
$query->select('img_url', 'item_id');
},
'brand' => function($query) {
$query->select('item_id', 'brand_id');
},
'brand.brand' => function($query) {
$query->select('brand_id', 'brand_name');
}
])
->select('item_id', 'short_name', 'price', 'price_above')
->orderBy('Price', 'Asc')->whereIn('category_id', $arr)
->groupBy('Sku')
->paginate(20);
my database structure is [st] https://screenshots.firefox.com/JAmaKENMYRhQkEjx/ourweds.com
this is item table migration
Schema::create('item', function (Blueprint $table) {
$table->bigIncrements('item_id');
$table->string('item_name');
$table->integer('Sku');
$table->text('Description');
$table->text('short_description');
$table->text('category_id');
$table->string('color');
$table->double('price');
$table->double('indian_price');
$table->string('old_price');
$table->string('indian_old_price');
$table->timestamps();
});
item eloquent model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class items extends Model
{
//
protected $table = 'items';
protected $primaryKey = 'item_id';
protected $fillable = [
'category_id',
'item_name',
'Sku',
'Description',
'short_description',
'color',
'kik_cash_percentage',
'status',
'price',
'price_old',
'indian_price',
'short_name',
'price_above',
'short_name_alter',
'availability'
];
public function pics(){
return $this->hasOne( 'App\item_pics', 'item_id' );
}
public function item_store()
{
return $this->hasMany('App\item_store','item_id');
}
public function category()
{
return $this->belongsTo('App\categories','category_id');
}
public function brand()
{
return $this->hasOne('App\item_has_brand','item_id');
}
}

Related

Store parent_id in laravel

I'm new to Laravel so I struggle. I have a comment system that worked perfectly fine but now I want to also add a reply system to it. So the way I decided to do it, is by adding a parent_id column to the comments table and then check if a comment has a parent. But I don't know how exactly the store method, in this case, should work. Here's my database set up for comments:
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->text('body');
$table->timestamps();
});
}
And now a set up for the reply column:
public function up()
{
Schema::table('comments', function (Blueprint $table) {
$table->unsignedBigInteger('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('comments');
});
}
Model:
class Comment extends Model{
use HasFactory;
protected $guarded = [];
public function post()
{
return $this->belongsTo(Post::class);
}
public function author()
{
return $this->belongsTo(User::class, 'user_id');
}
public function replies() {
return $this->hasMany('App\Comment', 'parent_id');
}
}
Controller:
public function store(Post $post){
request()->validate([
'body' => 'required'
]);
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('id'),
'body' => request('body')
]);
return back();
}
I just don't know how exactly I can get parent_id in the store function so I would appreciate some suggetstions
it should be the comment id that got the reply
something like this
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('comment_id'),
'body' => request('body')
]);
I hope it's helpful
use code :
public function store(Post $post) {
request()->validate([
'body' => 'required'
]);
$post->comments()->create([
'user_id' => request()->user()->id,
'parent_id' => request()->get('comment_id'),
'body' => request('body')
]);
return back();
}

Searching for a Laravel equivalent

I am beginner webdeveloper.
I have small problem my model.
I have this migration and model:
Schema::create('stopwatches', function (Blueprint $table) {
$table->increments('id');
$table->integer('case_id')->unsigned();
$table->foreign('case_id')->references('id')->on('case_instances')->onDelete('cascade');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
Schema::create('timecycles', function (Blueprint $table) {
$table->increments('id');
$table->integer('timecycleable_id');
$table->string('timecycleable_type');
$table->integer('case_id')->unsigned();
$table->foreign('case_id')->references('id')->on('case_instances')->onDelete('cascade');
$table->boolean('status')->default(0);
$table->integer('worked_time')->default(0);
$table->timestamps();
});
class Stopwatch extends Model
{
protected $fillable = [
'case_id',
'user_id'
];
protected $casts = [
'id' => 'int',
'case_id' => 'int',
'user_id' => 'int',
];
protected $dates = [
'created_at',
'updated_at'
];
public function timeCycle()
{
return $this->morphMany(Timecycle::class, 'timecycleable');
}
public function caseInstance()
{
return $this->belongsTo(CaseInstance::class, 'case_id');
}
class Timecycle extends Model
{
protected $fillable = [
'case_id',
'timecycleable_id',
'timecycleable_type',
'status',
'worked_time'
];
protected $casts = [
'id' => 'int',
'case_id' => 'int',
];
protected $dates = [
'created_at',
'updated_at'
];
public function stopwatch()
{
return $this->morphTo();
}
}
In timecycles I have 2 record with status = 0 and status = 1: https://ibb.co/5vyh316
I need my stopwatches with only one timecycles with status = 1.
I make this code:
return $this->stopwatch::with(['timeCycle', 'caseInstance'])
->where('user_id', Auth()->user()->id)
->where('updated_at', '<=', \Carbon\Carbon::now()->subSeconds(30)->toDateTimeString())
->whereHas('timeCycle', function ($q) {
$q->where('status', 1);
})
->get();
In result I have booth items: https://ibb.co/WnJ58Kc
What's wrong in my code?
How can I repair it?
Please help me.
You're actually quite close, but whereHas() doesn't affect the loaded records. Use the same clause on your with() statement:
return $this->stopwatch::with(['timeCycle' => function ($q) {
$q->where('status', 1); // If you only want 1, you can do `->limit(1)` as well
}, 'caseInstance'])
->where('user_id', Auth()->user()->id)
->where('updated_at', '<=', \Carbon\Carbon::now()->subSeconds(30)->toDateTimeString())
->whereHas('timeCycle', function ($q) {
$q->where('status', 1);
})
->get();
Now, when looping over your data, each $record->timeCycle will only include whatever is specified in the with() clause.
It's likely the problem is generated by the with('timeCycle') clause. If you want to constraint your query by a relation, you need to specified it in both the whereHas and the with(), otherwise the eager loading will fetch all the elements making the whereHas irrelevant. Try this:
return $this
->stopwatch::with([
'caseInstance',
'timeCycle' => function ($query) {
$query->where('status', 1);
}
])
->where('user_id', Auth()->user()->id)
->where('updated_at', '<=', now()->subSeconds(30)->toDateTimeString())
->whereHas('timeCycle', function ($query) {
$query->where('status', 1);
})
->get();
Of course, given both constraints are equal, you could store it in a variable and pass it to both methods:
$timeCycleContraint = function ($query) {
$query->where('status', 1);
};
return $this
->stopwatch::with([
'caseInstance',
'timeCycle' => $timeCycleContraint
])
->where('user_id', Auth()->user()->id)
->where('updated_at', '<=', now()->subSeconds(30)->toDateTimeString())
->whereHas('timeCycle', $timeCycleContraint)
->get();

Laravel 'get property of non-object'

I am trying to get (order_id, product_id and quantity) to be stored in Order Product table in database, so when placed an order it should store orders and order product in database . But now it only store orders and gives this error "Trying to get property of non-object".
I have tried some solutions from other sources but still not working.
CheckoutController
<?php
namespace App\Http\Controllers;
use App\Order;
use App\OrderProduct;
use Illuminate\Http\Request;
use cart;
class CheckoutController extends Controller
{
public function index()
{
return view('checkout');
}
public function create()
{
//
}
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'user_id' => auth()->user() ? auth()->user()->id : null,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
$cart = session('cart');
foreach(session('cart') as $products) {
OrderProduct::create([
'order_id' => $order->id,
'product_id' => $products->id,
'quantity' => $products->quantity,
]);
}
$cart = session()->remove('cart');
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
}
public function show($id)
{
//
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'product_id', 'quantity'];
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $fillable = [
'user_id', 'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Product')->withPivot('quantity');
}
}
Updated:
I have changed code now it shows quantity but can't show product_id it gives error "Trying to get property of non-object"
if ($order) {
foreach(session('cart') as $products) {
if (empty($products)) {
continue;
}
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $products['id'], //-> This not working
'quantity' => $products['quantity'],
]);

Laravel Eloquent : The wrong key name for model's relation

I made a Models controller and use it as resources for almost all my Model. Now, when I try to get the data of a model and the related models, Laravel replace upper case letter with an underscore and the lower case letter. I need to let it with the upper case.
So there is the model where I got the issue at App\Models\Rate:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Rate extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $table = 'rates';
protected $fillable = [
'institution_id',
'name',
];
protected $info = [
'relations' => [
'rateRistournes' => [
'model' => 'RateRistourne',
'type' => 'hasMany',
],
'rateRows' => [
'model' => 'RateRow',
'type' => 'hasMany',
],
'rateTables' => [
'model' => 'RateTable',
'type' => 'hasMany',
],
],
'rules' => [
],
'hashid' => false,
];
public function getRelations()
{
return $this->info['relations'];
}
public function getRules()
{
return $this->info['rules'];
}
public function useHashid()
{
return $this->info['hashid'];
}
public function institution()
{
return $this->belongsTo(Institution::class);
}
public function rateTables()
{
return $this->hasMany(RateTable::class);
}
public function rateRows()
{
return $this->hasMany(RateRow::class);
}
public function rateRistournes()
{
return $this->hasMany(RateRistourne::class);
}
}
And this is the function that contain the query into ModelsController:
public function show($name, $id)
{
$data = $this->retrieveModelAndRelations($name, $id);
if (is_null($data)) {
return $this->sendError('Model not found.');
}
return $this->sendResponse($data->toArray(), 'Model retrieved successfully.');
}
private function retrieveModelAndRelations($name, $id)
{
$modelName = 'App\Models\\'.$name;
$model = new $modelName;
if ($id === 'null') {
...
} else {
$data = $modelName::when(isset($model->getRelations()['customer']), function($query) {
return $query->with('customer');
})...
})->when(isset($model->getRelations()['rateTables']), function($query) {
return $query->with(array('rateTables' => function($q) {
$q->orderBy('cashStart', 'ASC');
}));
})->when(isset($model->getRelations()['rateRows']), function($query) {
return $query->with(array('rateRows' => function($q) {
$q->orderBy('rate', 'ASC');
}));
})->when(isset($model->getRelations()['rateRistournes']), function($query) {
return $query->with(array('rateRistournes' => function($q) {
$q->orderBy('ristourne', 'ASC');
}));
})->find($id);
}
return $data;
}
And there is the result into the console:
created_at:(...)
deleted_at:(...)
id:(...)
institution_id:(...)
name:(...)
rate_ristournes:Array(1)
rate_rows:Array(1)
rate_tables:Array(1)
The 3 last line should be:
rateRistournes:Array(1)
rateRows:Array(1)
rateTables:Array(1)
Is there a way to force laravel to keep the relation key as I wrote it?
Something under the hood change the name and I don't know how to bypass it.
Change $snakeAttributes:
class Rate extends Model
{
public static $snakeAttributes = false;
}

laravel create omits/skips fields

I'm trying to seed a couple of databases with laravel seeder, but it seems that it skips some fields..
I'm doing it this way:
Item::create(array(
'name' => 'Category 2',
'photo' => 'Description of category 2',
'order' => 1
'price' => 2.30
'category_id' => 1,
));
The fields 'category_id' and order are not setup in the database..
I'm calling the seeder this way
Artisan::call('db:seed',array('--database' => 'tenant_'.$user, '--class' => 'TenantSeeder'));
Any idea why does it happen?
If I use the standard
$item = new Item;
$item->allfields = "its_value";
$item->save();
It works perfectly
UPDATE
Here comes the model:
<?php
class Item extends Model {
//============================================================================
// PARENT VARIABLES
//============================================================================
protected $table = "items";
protected $softDelete = true;
protected $hidden = ['created_at','updated_at'];
protected $fillable = ['name','price','description','photo']; //Items that can be mass assigned
protected $guarded = array('id');
protected static $rules = [
'name' => 'required|min:3',
'price' => '',
'description' => '',
];
//============================================================================
// METHODS
//============================================================================
public function getId() { return $this->getKey(); }
public function getName() { return $this->name; }
public function getPhotoSrc() { return $this->photo; }
public function item_category(){
return $this->belongsTo('Items_category');
}
public function scopeActive($query)
{
return $query->where('active', '=', true);
}
}
And the Scheme
Schema::create('items', function(Blueprint $table)
{
// auto increment id (primary key)
$table->increments('id');
$table->string('name')->default('New Item');
$table->float('price')->default(0);
$table->string('photo')->nullable();
$table->integer('order')->unsigned();
$table->boolean('active')->default(true);
$table->string('description')->nullable();
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('items_categories')->onDelete('cascade');
// created_at, updated_at DATETIME
$table->timestamps();
$table->softDeletes(); //It is not really deleted, just marked as deleted
});
Any idea?
As User2094178 said,
I didn't have the fields in the $fillable

Categories