Laravel 4 - Method [where] does not exist - laravel

I am trying to get row from the table with "->find(X)" or "->where" but i get error in return. i guess i am missing something but i can't tell what.
<?php
class SnippetsController extends BaseController {
public $restful = true;
public function index($id)
{
$snippet = SnippetsController::where('id', '=', 11)->get();
i tried it with find but noting helps.
$snippet = SnippetsController::find(11);
with "->get" and without. but noting works. i do have the "11" id in the table itself and the error seems to have noting to do with it.
maybe i need to extend the class to Eloquent? if so, how do i keep the BaseController on top of it?
Thanks!
error:
BadMethodCallException Method [find] does not exist.

You must have a Model called Snippet, right? So this is how you use it:
$snippet = Snippet::find(11);
Your SnippetsController is not tied to a database (Eloquent ORM), so you must create (if you don't have already) a model:
class Snippet extends Eloquent {
}

Just edit the code $snippet = SnippetsController::where('id', '=', 11)->get(); with $snippet = Snippets::where('id', '=', 11)->get();. May be your model name is Snippets it may solve your problem.

Related

return table except deleted_at (softdeletes) laravel

I'm trying to return a table without deleted rows (softdeletes)
This is my code
public function getMailRecipients($meoId){
return DB::table('mail_recipients')->where('meo_id', '=', $meoId)->select('name', 'email')->get();
}
but I get all rows, even those removed through softdeletes, What else should I add to avoid that?
thanks!
you are using query builder (facade DB) in this case you should do this:
DB::table('mail_recipients')->where('meo_id', '=', $ meoId)->whereNull('deleted_at')->select('name', 'email')->get();
If you use the model, you must use the SoftDeletes trait
class Flight extends Model{
use SoftDeletes;
}
see more in the documentation
https://laravel.com/docs/8.x/eloquent#soft-deleting
Note *: The soft deleting feature works when using Eloquent. If you are querying the results with query builder you will eventually see all the records trashed and not trashed.
You can try with this:
public function getMailRecipients($meoId)
{
return DB::table('mail_recipients')
->whereNull('deleted_at')
->where('meo_id', $meoId)
->get(['name', 'email']);
}
If you arrived here because you are using protected $softDelete = true in your model and Laravel seems to ignore it, the solution is to use Illuminate\Database\Eloquent\SoftDeletes in your model. Works everytime!

How to retrieve multiple relations with multiple tables in laravel eloquent

I'm using Laravel 5.8 to build a babysitting site. I have 4 tables with different relationships as below:
please see this image
The relationships are:
Babysitter->hasMany(session)
Sessions->hasOne(Review)
Sessions->hasOne(Kids)
Sessions->hasOne(Babysitter)
Sessions->hasOne(Parent)
I want to achieve 2 things:
First one
I want to show this result when listing all babysitters. I'm showing this information for each babysitter:
plsease see this image
See here what I couldn't achieve
plsease see this image
This is my code
Sitters::where('Status', 'active')->where('Verified', 1)->get();
Second one
Also, I've tried to show kids name with parent review as shown here:
plsease see this image
This is what i'm using
Sessions::select('Reviews.*', 'Sessions.Parent_id')->join('Reviews', 'Reviews.Session_id', '=', 'Sessions.id')->with('owner')->where('Trainer_id', session('user')->Id)->where('Status', '=', 'complete')->with('owner')->orderBy('Sessions.id', 'DESC')->get();
Here is Session.php Model
public function owner(){
return $this->belongsTo('App\Models\Parents', 'Parent_id');
}
As discussed change the relations:
Babysitter->hasMany(sesstion)
Sessions->hasOne(Review)
Sessions->belongsTo(Kids)
Sessions->belongsTo(Babysitter)
Sessions->belongsTo(Parent)
First one
in Babysitter.php declare the following attributes
class Babysitter extends Model
{
public function reviews()
{
$this->hasManyThrough(Review::class, Session::class);
}
public function getAverageReviewAttribute()
{
return $this->reviews()->avg('Rating');
}
}
Then you just need to call it on the model instance.
$babysitter = Babysitter::first();
return $babysitter->average_review;
Second one
Just use the relation
$babysitter = BabySitter::with(['sessions' => public function ($session) {
$session->with(['review','parent','kids']);
})->where('trainer_id', '=', session('user')->Id) //did not understand this condition
->first();
This assumes you have parent, kids and review relation declared on Session::class. (change the names if needed)
After a few days of searching & testing, this is what worked for me:
Inside (Sitters) Model, put this relation
public function sessions()
{
return $this->hasMany(Sessions::class, 'sitter_id')
->withCount('reviews')
->withCount(['reviews as review_avg' => function($query){
$query->select(DB::raw('AVG(Rating)'));
}]);
}
Also, inside (Sessions) Model, put this relation
public function reviews()
{
return $this->hasOne(Reviews::class, 'Session_id');
}
Now you query like this
return $sitters = Sitters::with('sessions')->get();
I hope this can help someone :)

How to sort a query by the results of a model's method in Laravel

I have a model that has a "hasMany" relationship with a second model which records "votes" for the former. I then have a method which can be called upon to simply count the number of votes, as follows:
class Car extends Model
{
public function votes()
{
return $this->hasMany(Vote::class);
}
public function score()
{
return $this->votes->count();
}
}
In my controller, I want to run a query that returns all() but sorts by score()... something along the lines of:
$cars = Car::all()->sortBy('score');
But that doesn't work obviously... I feel like I'm on the right track, but don't quite know how to make this work. Would appreciate some help. Thanks.
Try this solution:
$cars = Car::with('votes')->get()->sortBy(function($car)
{
return $car->votes->count();
});
Hope it help you :)
the code should be like this :
$products = Shop\Product::join('shop_products_options as po', 'po.product_id', '=', 'products.id')
->orderBy('po.pinned', 'desc')
->select('products.*') // just to avoid fetching anything from joined table
->with('options') // if you need options data anyway
->paginate(5);

Laravel 5 Eager Loading with parameters

I'm working on a project with a bit of a complex model that has joins in its relations and also requires a parameter. It all works pretty well, except for when I need to eager load the relationship, as I couldn't figure out if there is a way to pass a parameter/variable to it.
The Controller
$template = Template::find($request->input('id'));
$this->output = $template->zones()->with('widgets_with_selected')->get();
The Model
public function widgets_with_selected($banner_id)
{
return $this->belongsToMany('App\Models\Widget', 'zone_has_widgets')
->leftJoin('banner_has_widgets', function($join) use($banner_id) {
$join->on('widgets.id', '=', 'banner_has_widgets.widget_id')
->where('banner_has_widgets.banner_id', '=', $banner_id);
})
->select('widgets.*', 'banner_has_widgets.banner_id');
}
This is returning a Missing argument error as the variable is not being passed.
I have resolved the issue by moving the logic to the controller, but I want to know if there is a way to keep the relationship in the model and just call it with a parameter.
Looking at the laravel code I dont think this is possible as you'd like to do it. You simply cant pass parameters to a with() call.
A possible workaround is to have an attribute on your model for $banner_id.
$template = Template::find($request->input('id'));
$template->banner_id = 1;
$this->output = $template->zones()->with('widgets_with_selected')->get();
Then change your relationship
public function widgets_with_selected()
{
return $this>belongsToMany('App\Models\Widget','zone_has_widgets')
->leftJoin('banner_has_widgets', function($join) use($this->banner_id) {
$join->on('widgets.id', '=', 'banner_has_widgets.widget_id')
->where('banner_has_widgets.banner_id', '=', $banner_id);
})
->select('widgets.*', 'banner_has_widgets.banner_id');
}
You could perhaps alter it a bit by passing the banner_id through a method. Sortof like this in your model:
public function setBanner($id) {
$this->banner_id = $id;
return $this;
}
Then you can do:
$template->setBanner($banner_id)->zones()->with('widgets_with_selected')->get();
Not sure if this works, and it's not really a clean solution but a hack.

Laravel 3 Eloquent ORM usage

I have the following code which works but doesn't seem to follow the laravel eloquent way:
Article::left_join('images', 'articles.id', '=', 'images.article_id')
->join('article_category', 'articles.id', '=', 'article_category.article_id')
->where('article_category.category_id', '=', $category_id)
->get();
I have 4 tables; articles and categories which have a many to many relationship with each other, a pivot table article_category table which holds the article id and category id and an image table which has one to one relationship with an article.
I setup my models as:
class Category extends Eloquent {
public static function get_articles($category_id) {
return static::find($category_id)->has_many_and_belongs_to('Article');
}
class Article extends Eloquent {
public function categories() {
return $this->has_many_and_belongs_to('Category');
}
public function image() {
return $this->has_one('Image');
}
However I can't seem to get all three bits of info together. I can do:
Category::get_articles($current_category)->get();
To get all articles in a given category but I can't seem to get the image for the article, there seems to be nothing I can chain onto? Unless I'm doing it incorrectly? Is there a trick I'm missing?
I even tried the stripped down version from the docs:
foreach (Article::with('image')->get() as $article) {
echo $article->image->foo;
}
However I get an error: Trying to get property of non-object, even though var_dump shows $article->image is an object! Weird.
Thanks
If you have not setup a model for the image table, do that. The ORM needs the model there so it knows what 'Image' refers to.
Can you get the category information using the ::with method or is that troublesome too?

Resources