Find model by a string - php

I'm having a hard time finding the problem in this repository method:
public function findByString($string)
{
return User::where('string', $string)->get();
}
It generates the correct SQL statement which I can run in Sequel Pro returning the right result.
However, when this method is called in Laravel (4.2), the result is always empty:
$this->user->findByString('something');
On the other side
$this->user->findOrFail(1);
Always returns the correct model.
Any ideas what could be wrong?

return User::where('string', $string)->get();
Will return a collection that you can iterate through.
If you want the first instance back as an Eloquent model you can do this:
return User::where('string', $string)->first();

Related

Why query result suddenly changed after called from other medthod in Laravel

I have problem here with query result from Eloquent, I tried to query from DB and put in variable $contractList in my mount() method and the result as expected. But when I tried to retrieve specific data from $contractList with $contractList->find($id), the result not same as in mount() method.
Here is query from mount():
public function mount(){
$contractList = Kontrak::select(['id', 'mou_id'])->with(['order:id,kontrak_id', 'order.worklist:id', 'order.worklist.khs:id,mou_id,worklist_id,khs', 'amdNilai:id,kontrak_id,tgl_surat'])->withCount('amdNilai')->get()
}
Here the result:
But when I tried to find specific data from $contractList, properties that shown not same as in mount:
public function itemSelected($id)
{
//amd_nilai_count not showing
$kontrak = $this->contractList->find($id);
if ($kontrak->amd_nilai_count == 1) {
$this->nilai_amd = $this->calculateNilai($id);
}
}
Here is the result called from itemSelected():
I have tried use get() but the result still problem, how to get same properties same as in mount().By the way im use laravel & livewire.
As i read your comments you seem to mix up ActiveRecords ORM with an Data Mapper ORM. Laravel uses active records.
Laravel will always fetch models on every data operation.
Kontrak::select('name')->find(1); // select name from kontraks where id = 1;
Kontrak::find(1); // select * from kontraks where id = 1;
This will always execute two SQL calls no matter what and the objects on the heap will not be the same. If you worked with Doctrine or similar, this would be different.
To combat this you would often put your logic in services or similar.
class KontrakService
{
public function find(int $id) {
return Kontrak::select(['id', 'mou_id'])->find($id);
}
}
Whenever you want the same logic, use that service.
resolve(KontrakService::class)->find(1);
However, many relationship operations is hard to do with this and then it is fine to just fetch the model with all the attributes.

wasRecentlyCreated and wasChanged are not working

I am trying to use wasChanged and wasRecentlyCreated of models in laravel project but both of them are false in the below code
$saved=$project->accessInfo()->updateOrCreate(['type'=>$request->type],['value'=>$data]);
dd($project->accessInfo[0]->wasChanged(),$project->accessInfo[0]->wasRecentlyCreated,$project->wasRecentlyCreated,$project->wasChanged());
//here is my relation in Project model
public function accessInfo()
{
return $this->hasMany('Modules\Project\Models\ProjectAccessInfo', 'project_id');
}
also below code returns error
dd($project->accessInfo->wasChanged(),$project->accessInfo()->wasRecentlyCreated)
//No such method or attribute in both cases
//Call to undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::wasChanged()
Thanks in advance for your help.
getChanges - Get the attributes that were changed.
getDirty - Get the attributes that have been changed since last sync.
When you want to know if the model has been edited since it was queried from the database, or isn't saved at all, then you use the ->isDirty() function.

GroupBy and OrderBy Laravel Eloquent

Building a chat application with a dashboard and am trying to get a notification of the last message the that other user sent.
Here is my Model relationships:
public function messages() {
return $this->hasMany('App\Message', 'author_id');
}
public function lastMessage() {
return $this->hasMany('App\Message', 'recipient_id')->orderBy('created_at', 'DESC')->groupBy('author_id');
}
On thing I cant figure out is instead of returning the last message as it should be sorted by using orderBY, it returns the first record of that group that exists in the database.
Looked around online but cant seem to find any info on this. The only thing I found is a post by someone who said that orderBy and groupBy in laravel don't play well together.
Any help is appreciated!
Instead of redefining the relationship in lastMessage, you might try calling messages from it and then running your query from that.
Without seeing more of your model schema (ie: where are these relationships defined??), this might not be perfect, but it's a start:
public function lastMessage()
{
return $this->messages() // <-- Notice the ()...this creates a query instead of immediately returning the relationship
->where('recipient_id', $this->id) // Not sure if this is correct, might need to adjust according to how you have defined the tables
->orderBy('created_at', 'desc')
->first();
}
It will query the messages relationship with the chained constraints that are listed. And by returning first() it returns only one record as opposed to a collection.

Laravel 5 where method not working

I'm trying to query records using a parameter from a route, but it's not working properly.
This is my route:
Route::get('reports/{id}', 'ReportsController#show');
This is my controller method:
public function show($id) {
return Reports::all()->where('user_id', $id);
}
When accessing the route 'reports/1', it returns nothing. However, if I hardcode in the id to use in the method, it does work:
public function show($id) {
return Reports::all()->where('user_id', 1);
}
I don't know what is wrong with my code, please help.
Your issue is that you're calling where() on a Laravel Collection, not on a Laravel Query Builder.
Reports::all() will run a query that will get every single report from the database and put it into a Collection. You're then running the where() method on that Collection.
The difference is that the where() method on a Collection loops through the items in the collection, and does a strict comparison (===), whereas the query builder adds a parameterized where clause to the SQL, which doesn't care about the variable type.
What you're running into is that when using the variable, you're running where('user_id', '1'), which is doing a strict comparison (===) of the user_id field to the string '1'. Since all the user ids are integers, you won't get any results.
What you really want to do is add your where conditions to the SQL statement. Instead of your current logic, you want:
public function show($id) {
return Reports::where('user_id', $id)->get();
}
This will fix your issue, as well as only return those records that match your where clause, which may severely boost your performance. If you have a million reports, you don't want to build a collection of a million objects, and then iterate through them.

Laravel, Scope Methods on Model

im writing a Laravel Application, that calculates monthly income.
Income table has a column that saves this monthly value. In some months the value will be 0 but when I access to the method using:
$service->income->getMonthTotal(11);
I get the following error (HasOne could not be converted to string)
This is the scope method i'm using, where $result is returning 0, and laravel is giving me the error.
Any ideas on how to return 0 for echoing value?
public function scopeGetMonthTotal($query, $month)
{
$result = $query->where('month',$month)->sum('value');
return $result;
}
Accessing relationships as properties will automatically run get(), resulting in your error. You need to access your relationship as a method instead:
$service->income()->getMonthTotal(11);
To see the result, make sure to run get() yourself:
echo $service->income()->getMonthTotal(11)->get();

Categories