Scope left Join Sub doesn't work - Laravel - laravel

I'm new to Laravel I'm making a clone of Twitter. I'm making a scope to get all the likes from the DB, but I get an error from Tinker
I know some basic SQL Queries, but this one is quite complicated, so I've got no idea what to do now.
Tweet model
public function scopeWithLikes(Builder $query)
{
$query->leftJoinSub(
'select tweet_id, sum(liked) likes, sum(!liked) dislikes from likes group by tweet_id',
'likes',
'likes.tweet_id',
'tweet.id'
);
}
Tinker command
App\Tweet::withLikes()->first();
Tinker error
TypeError: Argument 1 passed to App/Tweet::scopeWithLikes() must be an
instance of Illuminate/Database/Query/Builder, instance of
Illuminate/Database/Eloquent/Builder given, called in
C:/wamp64/www/laravel/tweety/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
on line 1164
I hope I explained it well, but if you need more information please ask me.
Thanks for your answer!

i think that you are using the wrong class for your scope, scope use
Illuminate/Database/Query/Builder
as a parameter while you pass
Illuminate/Database/Eloquent/Builder
in your Twit model file, on the top ...
remove:
use Illuminate/Database/Eloquent/Builder;
and paste:
use Illuminate/Database/Query/Builder;

Did this solve the problem? Because I run into exactly the same issue.
When I change Eloquent to Query, the error message is still the same.
Also the source that is given on Git uses use
Illuminate\Database\Eloquent\Builder;
Hubert

Related

Illuminate\Database\Eloquent\RelationNotFoundException Call to undefined relationship [user] on model [App\Event]

I'm creating a view list for M-M relationship for Admin view. I want to display every user that has been registered for that particular events. And I'm pretty sure I called it wrong thats the reason why I getting this error. I'm not quite sure on how to fix it. I tried googling and I still don't find any solution yet. So how can I fix this?
The relation name is users not user. Please check using below code
use DB;
use App\Event;
use App\User;
public function show()
{
$events = Event::with('users')->get();
return view('admin.event.user')->with('events', $events);
}

Two models, two fields, return preferred if present

Been struggling with how to do this the most optimized way possible...
I have two models: Catalog and Application.
Catalog has a field called name.
Application has a field called name.
Both have a relationship with each other.
I am struggling to find a way to create a function i could use across my Laravel application which i would pass application.id to it and it would return a $app->name value based on the following logic:
if $application->name exists, use this value as the $app->name for the $application object
otherwise, get the $catalog->name value and use it as the $app->name
Note that I would like to create a component #application() where i can simply pass the $application->id and build the display logic (theming/styling) into it.
Since i display this $app->name in many places, i would like to make it as lightweight as possible to avoid unnecessary queries.
I hope this makes sense! There are probably so many ways to go with it, i am lost at figuring out the way way to do this :(
I'm not completely sure to understand your model/DB design, but you could use a custom Helper to use that function through the whole app.
For that, you can create a simple PHP class Helper.php file in app/Http/Helpers folder or whatever location you want. Something like:
<?php
use App\Catalog;
use App\Application;
if (! function_exists('getAppName')) {
function getAppName($id){
// Do your logic here to return the name
$catalog = Catalog::find($id);
return $catalog->name;
}
}
?>
Then in any controller or view, you just do
getAppName($application->id)
Do no forget to add your helpers file to the composer autoload. So in composer.json in Laravel's root folder, add the helper path to the autoload array:
"files": [
"app/Http/Helpers/helpers.php"
],
Last but not least, run the following command:
composer dump-autoload
Please note that function logic is just for sample purposes since I don't know your model structure.
In my opinion, I care about the database cost.
Use ternary expression will be elegant. But it took two times IO costs from database if application name is empty.
$app_name = Application::find($id)->name;
$app_name = empty($app_name) ? Catalog::where('application_id', $id)->first()->name;
And this will more complicated, but the catalog_query only execute when application.name is empty, it execute in database and the result is taken out only once;
And Database will only find the name from one table or two table.
Something like this:
$catalog_query = Catalog::where('catalogs.application_id', $id)->select('catalogs.name')->groupBy('catalogs.name');
// if catalogs and applications relationship is 1:1, use ->limit(1) or remove groupBy('name') is better.
Application::where("applications.id", $id)
->selectRaw("IF(application.name IS NULL OR application.name = '', (" . $catalog_query->toSql() ."), applications.name ) AS app_name")
->mergeBindings($catalog_query->getQuery())
->first()
->app_name;
Hope this will help you.

Where to put user related get functions

I have a problem I am working on for quite a while now.
I am using Laravel 5.0 and have relationships set up:
A user can have many itineraries
A itinerary can have many destinations
A user has many destinations through itineraries
Now I am trying to set up a function which I need in many controllers. I have this function in User.php:
public function last_destination() {
return $last_destination =
\App\Destination::where('itinerary_id', auth()->user()->active_itinerary_id)
->orderBy('order_index', 'DESC')
->first();
}
When I try to retrieve the last destination, it works fine, but when I pass the last destination as a variable to a view, it throughs me the error: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
Should I put this function in another class? If so where should I put it to still be able to call it as $user->last_destination()?
I appreciate any help!
Thanks a lot!
Sebastian
You are most likely trying to call $user->last_destination somewhere, as you would if that method returned a Relation.
Try using $user->last_destination() instead. Or updating your method to return a Relation instance.

laravel newbie- syntax for making/setting variable in view with a function in the controller

I've started my first project in laravel (following along with the beginner laracasts series). I've successfully made a 'joggers' scope and get_joggers() function in the controller to pass that set of data to a view- great!
So now- I have a view where I pass all the people, and a partial to show different subsets of them, like so:
#include ('partials._people_list', ['person_group' => $joggers]);
My question: On a view page, what's the syntax declare/set a variable to the results of a function in the controller? I would imagine something like this, but since a view page wants HTML I'd at least have to put it in some php tags or something (though there's probably a better way):
$person_group = action('PeopleController#get_joggers');
This seems so painfully basic, but the first 27 laracasts didn't get there and I've been hunting around for while. Thanks in advance for any help!
Update! I talked to a buddy at work, and the answer was to make/set $joggers in the PeopleController, and then pass it all along like so:
public function index()
{
$people = Person::latest('created_at')
->displayable()
->orderBy('last', 'asc', 'first', 'asc')
->get();
$joggers= Person::joggers('created_at')->get();
return view('person.index', compact('people', 'joggers'));
I've returned different types of data before, and it hadn't occurred to me that I could send two different collections of people. Mystery solved :)

Laravel created_by/modified_by relations

I was trying to get this working in a typical belongsTo relation. However it keeps saying that the column is not set in the model, even if looking in the actual database it is there.
I have tried to look at the source code as well as try many approaches to bypass this issue, however nothing seems to do anything.
public function modifiedBy()
{
return $this->belongsTo('\Modules\Users\Model\User', 'modified_by');
}
public function createdBy()
{
return $this->belongsTo('\Modules\Users\Model\User', 'created_by');
}
This is the code inside the model, I use PSR-0 to define modules, better splitting up logic (no issues with that) but using this it would give an error of
Undefined property: \Modules\Module\Model\CurrentModel::$modified_by
This is coming from a seed to push some initial info into the database.
$user = Sentinel::findById(1);
$model = new CurrentModel;
$model->modifiedBy()->associate($user);
$model->save();
This is basically how it goes together, I have tried for some time to figure out what is wrong but I am calling blanks. Any ideas?
Found out a solution. Not a fix though but I would consider this an issue with laravel so I may look into adding it as a bug report (although this could be fixed in laravel 5?).
Basically with modified_by I need to define the column it is using and not let laravel automatically generate it (in order to do this "cleanly"). However the "bug" (only calling it a bug as currently I can only see this as an unintended problem) makes it so you cannot define the column it will be using, you have to let laravel decide it for you.
So I changed the functions to look like this:
public function modifiedby()
{
return $this->belongsTo('\Modules\Users\Model\User');
}
This makes laravel assume the column is modifiedby_id, but by changing my migrations to reflect that there was no more error.

Resources