Laravel 5.5 - Method paginate not found - php

I don't know what's wrong, but here's my script at my AppController.
function getData () {
$list_data = MyModel::all()->sortBy('id')->paginate(15);
$count_data = $list_siswa->count();
return view('pages.list', ['list' => $list_data, 'count' => $count_data]);
}
And here's my model
class MyModel extends Model {
protected $table = 'students';
protected $fillable = [
'id',
'name',
'class',
'gender',
'address'
];
}
Any idea? I think the problem is in my controller.

You must paginate a database query not a collection, therefore you must user orderBy instead of combining all with sortBy, I have tested the below code and can confirm it works
function getData () {
$list_data = MyModel::orderBy('id')->paginate(15);
$count_data = $list_data->count();
return view('pages.list', ['list' => $list_data, 'count' => $count_data]);
}

Related

Return default value if belongTo relation is returned null

I have a belongTo relation, if join condition is matched then ok but when there is no data for this it returns null. In this case, I want it returns default value as I expected. This is what I try but it not success. Please help me?
class Task extends Model
{
use SoftDeletes;
protected $table = 'tasks';
protected $fillable = [
'name',
'description',
'project_id',
];
protected $with = ['project', 'status'];
// this is expected
public function getProjectAttribute($value)
{
return $value ?? ['id' => '', 'name' => ''];
}
/**
* #return App\Modules\Com\Models\Project
*/
public function project()
{
return $this->belongsTo(Project::class, 'project_id', 'id')->select(['id', 'name']);
}
}
With description attribute, I can override it but why I dont the same thing with project attribute? And how do I set where for project relation?
Like this Task::select(*)->project()->where('project.name', 'ABC');.
I've never used Laravel -- but... the documentation shows that you can set a default for belongsTo when using it for updating in order to avoid conditional checks. Perhaps it will work for selecting too.
You can try adding the default to the end of your call.
return $this->belongsTo(Project::class, 'project_id', 'id')
->select(['id', 'name'])
->withDefault([
'project_id' => 'project.name',
'id' => 'ABC',
]);
Source: https://laravel.com/docs/6.x/eloquent-relationships#default-models
or
You could do a conditional check:
public function project()
{
$return $this->belongsTo(Project::class, 'project_id', 'id')->select(['id', 'name']);
if( $return === null )
// return your default values
else
return $return;
}

Laravel Eloquent method updateOrCreate exceeds execution time when updating

So the problem is that when I try to update my entity it finds it updates it but gets stuck in a loop probably and doesn't exit. When I check the database, even before the 60 seconds of execution time that I have expires, the values that I have changed are updated.
If i constantly refresh (and here is where it gets crazy) the updated at values for other lectures starts to change every second while it executes this loop.
When creating (not finding the id on the condition It creates it without a problem)
I have Lectures which looks like this:
class Lecture extends Model
{
use Searchable;
use SoftDeletes;
protected $primaryKey = 'id';
protected $touches = ['themes', 'educationTypes', 'subjects'];
protected $fillable= [
'name', 'description', 'user_id', 'field_id', 'approved'
];
public static function boot()
{
parent::boot();
static::saved(function ($model) {
$model->themes->filter(function ($item) {
return $item->shouldBeSearchable();
})->searchable();
});
}
public function user(){
return $this->belongsTo('App\User')->with('companies');
}
public function geographies(){
return $this->belongsToMany('App\Geography');
}
public function educationTypes(){
return $this->belongsToMany('App\EducationType', 'lecture_education_type')->withTimestamps();;
}
public function themes(){
return $this->belongsToMany('App\Theme','lecture_theme', 'lecture_id', 'theme_id')->withTimestamps();;
}
public function subjects(){
return $this->belongsToMany('App\Subject', 'lecture_subject')->withTimestamps();;
}
public function cases(){
return $this->belongsToMany(
'App\CompanyCase' ,
'case_company_lecture',
'lecture_id',
'case_id',
'id',
'id')->withTimestamps();
}
public function companies(){
return $this->belongsToMany(
'App\Company' ,
'case_company_lecture',
'lecture_id',
'company_id',
'id',
'id'
);
}
public function field(){
return $this->belongsTo('App\Field');
}
public function toSearchableArray()
{
$this->themes;
$this->user;
$this->educationTypes;
$this->subjects;
$this->geography;
return $this->toArray();
}
}
This is the controller:
public function storeLecture(Request $request) {
$lecture_id = $request->get('lecture_id');
// It gets stuck between the comments
$lecture = Lecture::updateOrCreate(['id' => $lecture_id],
[
'name'=> request('name'),
'description'=> request('description'),
'user_id'=> request('user_id')]
);
// and doesn't update the themes, edu types subjects and etc.
$company_id = $request->get('company_id');
$company = Company::find(request('company_id'));
$lecture->companies()->sync([$company->id]);
$eduTypes= $request->get('education_types');
$themes= $request->get('themes');
$subjects = $request->get('subjects');
$geographies = $request->get('geographies');
$lecture->themes()->sync($themes);
$lecture->educationTypes()->sync($eduTypes);
$lecture->subjects()->sync($subjects);
$lecture->geographies()->sync($geographies);
$n1 = new Notification();
$n1->send(request('user_id'), 1, 'new_lecture', $lecture->id);
$user = User::where('id', $request->id)->first();
$user_with_companies = $user->load('companies');
$slug = $user_with_companies->companies->first()->slug;
return response(['success' => true]);
}
This is the frontend method sending the request (in between I have a middleware checking if the user is admin (possible to create a lecture) based on the this.selectedExpert.id, which doesn't interfere).
createUpdateLecture() {
const url = `${window.location.origin}/lecture/create/${
this.selectedExpert.id
}`;
this.$http
.post(url, {
education_types: this.allEducationTypes
.filter(el => el.checked)
.map(a => a.id),
themes: this.allThemes.filter(el => el.checked).map(a => a.id),
geographies: this.allGeographies
.filter(el => el.checked)
.map(a => a.id),
subjects: this.allSubjects.filter(el => el.checked).map(a => a.id),
name: this.lecture.name,
description: this.lecture.description,
user_id: this.selectedExpert.id,
company_id: this.company.id,
lecture_id: this.lecture.id
})
.then(res => {
console.log(res);
this.$parent.showLectureCreateModal = false;
// window.location.reload();
});
}
As I can see what is happening I probably use the method really badly but I just want to understand it better for further usage.
After a few days of researching and testing it turns out that it is not the updateOrCreate method causing the problem because I tried with two different functions for creating and updating and the update function was still having the same problem.
The problem is created from Algolia which is used for searching based on different fields in the platform. Fx. in Themes
class Theme extends Model
{
use SoftDeletes;
use Searchable;
protected $touches = ['lectures'];
public function lectures(){
return $this->belongsToMany('App\Lecture');
}
public function toSearchableArray()
{
$this->lectures;
return $this->toArray();
}
}
Removing the searchable from the models did the trick!

Laravel DD helper not executing inside each function

I'm currently trying to troubleshoot my way through duplicating an object with its appropriate relationships. I usually use Laravel's DD helper to see if I'm getting the right information, but in this instance, I don't think that it's being run when it hits the line in the method that gets executed.
Here's my controller method that's handling the duplication.
$copiedManagementSystem = $managementSystem->replicate();
$copiedManagementSystem->inspections->each(function($inspection) {
$copiedInspection = $copiedManagementSystem->inspections()->create([
'name' => $inspection->name,
'management_system_id' => $inspection->managementSystemId,
'pass_score' => $inspection->passScore,
'max_score' => $inspection->maxScore,
'order' => $inspection->order,
]);
dd($inspection); //I've placed the dd here but it doesn't work in any position, in any part of the each function.
$inspection->checks->each(function($check){
$copiedInspection->checks()->create([
'question' => $check->question,
'values' => $check->values,
'type' => $check->type,
'inspection_id' => $check->inspectionId,
'order' => $check->order,
]);
});
});
$copiedManagementSystem->save();
Here is the ManagementSystem's model with the inspections relationship
class ManagementSystem extends Model
{
protected $table = 'management_systems';
protected $fillable = ['name', 'description'];
public function inspections()
{
return $this->hasMany(Inspection::class);
}
}
This is the inspection's model with the relations
class Inspection extends Model
{
protected $table = 'inspections';
protected $casts = [
'order' => 'integer'
];
protected $fillable = [
'name',
'management_system_id',
'pass_score',
'max_score',
'order'
];
public function checks()
{
return $this->hasMany(Check::class);
}
public function managementSystem()
{
return $this->belongsTo(ManagementSystem::class);
}
}
And finally, here is the check model with its relations.
class Check extends Model
{
protected $table = 'checks';
protected $fillable = [
'question',
'values',
'type',
'inspection_id',
'order'
];
public function inspection()
{
return $this->belongsTo(Inspection::class);
}
public function answers()
{
return $this->hasMany(Answer::class);
}
}
I'd really appreciate any help :)
EDIT: So I've come across a strange occurrence. If I run the following:
dd($copiedManagementSystem->inspections->count();
It returns 0. But if I run:
dd($managementSystem->inspections->count());
It returns 12, which is the correct value.
Does anyone know why this happens? And if so, how can I fix the issue?
Thank you!
Since replicate() does not replicate the relations you could try something like this.
$copiedManagementSystem = $managementSystem->replicate()
foreach($managementSystem->inspections as $inspection) {
$copiedManagementSystem->inspections->attach($inspection->replicate())
}
It is pseudo code, if you want the original inspections linked remove the $inspection->replicate() call and just use $inspection
Same goes for any other relations $managementSystem might have.

Laravel 5: Having trouble updating related model values by using save/push methods, they just don't work

I'm trying to update some values of a related model but after assigning the new values and using save() or push() the values are not updated in database. More than that, execution just stops at those methods and all I can see is a blank page. No errors, no nothing, it just doesn't even reach the return statement. If I use the try-catch, it just skips the save() or push().
Here is the Product model (just without the fields and methods that are not related to what I'm currently trying to do):
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $table = "products";
public $timestamps = false;
public $fillable = [
...
];
public function userProduct()
{
return $this->belongsTo("\\App\\Models\\UserProduct", "id", "product_id");
}
}
The UserProduct model with fields which I'm trying to update:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UserProduct extends Model
{
protected $primaryKey = null;
public $incrementing = false;
protected $table = "user_product";
public $fillable = [
...
"is_featured",
"is_hidden_from_latest"
...
];
public function product()
{
return $this->belongsTo("\\App\\Models\\Product", "product_id", "id");
}
public function pendingProduct()
{
return $this->belongsTo("\\App\\Models\\PendingProduct", "target_product_id", "target_product");
}
}
Code from the controller:
$replaced_product_sku = Input::get("replaced_sku");
$new_product_sku = Input::get("new_sku");
$products = Product::with([
"userProduct" => function($q) {
$q->orderBy("updated_at", "asc");
}
])->where("product_status", "live")->get();
if (!$found_replaced = $products->where("item_sku", $replaced_product_sku)->first()) {
return redirect("admin/content")
->with("danger", "Replaced product was not found.");
}
if (!$found_new = $products->where("item_sku", $new_product_sku)->first()) {
return redirect("admin/content")
->with("danger", "The new featured product was not found.");
}
$found_replaced->userProduct->is_featured = 0;
$found_replaced->userProduct->is_hidden_from_latest = 1;
$found_new->userProduct->is_featured = 1;
$found_new->userProduct->is_hidden_from_latest = 0;
$found_replaced->userProduct->save();
$found_new->userProduct->save();
return redirect("admin/content")
->with("...", "...");
Tried using push() method instead of save() but the only thing that happens is that execution stops at $found_replaced->userProduct->save(); and a blank page is displayed. Also tried something like this:
$found_replaced->update([
"userProduct.is_featured" => 0,
"userProduct.is_hidden_from_latest" => 1
]);
$found_new->update([
"userProduct.is_featured" => 1,
"userProduct.is_hidden_from_latest" => 0
]);
but still without success.
First you have to fix the relations:
In Product model:
public function userProduct()
{
return $this->hasOne("\\App\\Models\\UserProduct", "product_id", "id");
}
In UserProduct model:
public function product()
{
return $this->belongsTo("\\App\\Models\\Product", "product_id", "id");
}
The solution was using this approach:
$found_replaced->update([
"userProduct.is_featured" => 0,
"userProduct.is_hidden_from_latest" => 1
]);
$found_new->update([
"userProduct.is_featured" => 1,
"userProduct.is_hidden_from_latest" => 0
]);
that I've posted in the question, but the mistake was that I was using it wrong, so I've edited it into this and it worked fine:
$found_replaced->userProduct()->update([
"is_featured" => 0,
"is_hidden_from_latest" => 1
]);
$found_new->userProduct()->update([
"is_featured" => 1,
"is_hidden_from_latest" => 0
]);
Seems that save() just doesn't work as expected on relation attributes.
Thank you for your help anyway! ;)

Laravel 3 - Eloquent query returns rules

I'm trying to send use models for the first time and running into a confusion. When I run a query, the rules are linked with it, is it supposed to be like that?
Model:
class User extends Elegant
{
public static $table = 'users';
protected $rules = array(
'email' => 'required|email',
'firstname' => 'required',
'lastname' => 'required',
'initials' => 'required|alpha|match:/[A-Z]+/',
'role' => 'required|in:writer_fr,writer_en,reader',
'password' => 'min:6,max:32|same:password2'
);
public static function has_role($role)
{
//$u = new User;
$users = User::where($role, '=', 1)->get(array('firstname', 'lastname'));
return $users;
}
}
Controller
$u = array();
$u['writer_en'] = User::has_role('writer_en');
dd($u['writer_en']);
Which prints out the entire model rules, messages, relationship etc logic. Am I doing something wrong or is this normal?
In your has_role method you are returning User model
public static function has_role($role)
{
//$u = new User;
$users = User::where($role, '=', 1)->get(array('firstname', 'lastname'));
return $users; // <-- User model
}
So, it's dumping the User model and it's doing the right thing as it suppose to do by following code
$u = array();
$u['writer_en'] = User::has_role('writer_en');
dd($u['writer_en']);
Instead of dumping the model, you can use
$user = User::has_role('writer_en');
echo $user->firstname;
echo $user->lastname;

Categories