Laravel Join Returning odd values - php

Just come across a bug on my Join query.
I am echoing out data in a foreach, and showing the username. On other pages it works fine and each username matches the username from the ID in the row. However, in the example below the username return is ALWAYS the name of the logged in user.
Hope the below makes some more sense. Thanks.
The query is:
$query = DB::table('blogs')
->join('followers', 'blogs.id', '=', 'followers.blogid')
->where('followers.userid', Auth::user()->id)
->where('frontpage', '1')
->latest('lastupdated');
This is called via:
Route::get('following', array('before' => 'auth', function()
{
$slug = Route::getCurrentRoute()->uri();
$builds = Blog::findBuilds($slug);
return View::make('pages/home', compact('builds'), array('pageTitle' => 'Builds You Are Following'));
}));
And then on the pages/home I am showing the data like so:
foreach ($builds as $build)
{
$usernameOfOwner = User::usernameFromID($build->userid);
}
And then... the function for getting the username from ID is:
public static function usernameFromID($id) {
$user = DB::table('users')->where('id', $id)->first();
return $user->username;
}
Everywhere else on my website when I run a query similiar to the top one but not a join so e.g.:
$query = static::where('frontpage', '1')->latest('lastupdated');
It works fine, so my only guess is that its down to the Join as thats the only different part of the code.

The problem is that you have multiple columns named userid. followers.userid and blogs.userid. Now in this case, unfortunately followers.userid gets returned when you use $build->userid
You can change that by only selecting the columns you want in your result.
$userid = Auth::user()->id;
$query = DB::table('blogs')
->join('followers', function($q) use ($userid){
$q->on('blogs.id', '=', 'followers.blogid');
$q->where('followers.userid', '=', $userid);
})
->select('blogs.userid', 'other-column')
->where('frontpage', '1')
->latest('lastupdated');
By the way: * works too, so you can do select('blogs.*') if you want

Related

LARAVEL: How to fetch id dynamically in a query builder?

I want to join multiple tables in laravel with query builder. My problem is that my code only works if I specify the id myself that I want like this:
$datauser = DB::table('users')
->join('activitates','users.id','=','activitates.user_id')
->join('taga_cars','taga_cars.id','=','activitates.tagacar_id')
->join('clients','users.id','=','clients.user_id')
->where('users.id','=','1')
->select('users.*','activitates.*','taga_cars.model','taga_cars.id','clients.name')
->get();
return response()->json($datauser);
But I would want something like this(which I just can't seem to figure out)
public function showuser($id)
{
$userid = User::findOrFail($id);
$datauser = DB::table('users')
->join('activitates','users.id','=','activitates.user_id')
->join('taga_cars','taga_cars.id','=','activitates.tagacar_id')
->join('clients','users.id','=','clients.user_id')
->where('users.id','=',$userid)
->select('users.*','activitates.*','taga_cars.model','taga_cars.id','clients.name')
->get();
return response()->json($datauser);
}
Am I making a syntax mistake? When I check the page for my json response in second page it just returns empty brackets, but when I specify the id it fetches me the right data
The findOrFail method will return the entire user model, with all its properties, since you already have the user id. You dont need to get the entire user model for that, you could just use the $id you receveid as a parameter like this:
$datauser = DB::table('users')
->join('activitates','users.id','=','activitates.user_id')
->join('taga_cars','taga_cars.id','=','activitates.tagacar_id')
->join('clients','users.id','=','clients.user_id')
->where('users.id','=',$id)
->select('users.*','activitates.*','taga_cars.model','taga_cars.id','clients.name')
->get();
return response()->json($datauser);
public function showuser($id)
{
$getUserByID = User::findOrFail($id); //not used
$userData = DB::table('users')
->join('activitates','users.id','=','activitates.user_id')
->join('taga_cars','taga_cars.id','=','activitates.tagacar_id')
->join('clients','users.id','=','clients.user_id')
->where('users.id','=',$id)
->select('users.*','activitates.*','taga_cars.model','taga_cars.id','clients.name')
->get();
return response()->json($userData);
}
But the best way is to have relations set on models
public function showuser($id)
{
$userData = User::where('id', $id)->with(['activitates','taga_cars','clients'])->first();
return response()->json($userData);
}

How to fetch users not assigned to a particular role in Laravel [duplicate]

In Laravel we can setup relationships like so:
class User {
public function items()
{
return $this->belongsToMany('Item');
}
}
Allowing us to to get all items in a pivot table for a user:
Auth::user()->items();
However what if I want to get the opposite of that. And get all items the user DOES NOT have yet. So NOT in the pivot table.
Is there a simple way to do this?
Looking at the source code of the class Illuminate\Database\Eloquent\Builder, we have two methods in Laravel that does this: whereDoesntHave (opposite of whereHas) and doesntHave (opposite of has)
// SELECT * FROM users WHERE ((SELECT count(*) FROM roles WHERE user.role_id = roles.id AND id = 1) < 1) AND ...
User::whereDoesntHave('Role', function ($query) use($id) {
$query->whereId($id);
})
->get();
this works correctly for me!
For simple "Where not exists relationship", use this:
User::doesntHave('Role')->get();
Sorry, do not understand English. I used the google translator.
For simplicity and symmetry you could create a new method in the User model:
// User model
public function availableItems()
{
$ids = \DB::table('item_user')->where('user_id', '=', $this->id)->lists('user_id');
return \Item::whereNotIn('id', $ids)->get();
}
To use call:
Auth::user()->availableItems();
It's not that simple but usually the most efficient way is to use a subquery.
$items = Item::whereNotIn('id', function ($query) use ($user_id)
{
$query->select('item_id')
->table('item_user')
->where('user_id', '=', $user_id);
})
->get();
If this was something I did often I would add it as a scope method to the Item model.
class Item extends Eloquent {
public function scopeWhereNotRelatedToUser($query, $user_id)
{
$query->whereNotIn('id', function ($query) use ($user_id)
{
$query->select('item_id')
->table('item_user')
->where('user_id', '=', $user_id);
});
}
}
Then use that later like this.
$items = Item::whereNotRelatedToUser($user_id)->get();
How about left join?
Assuming the tables are users, items and item_user find all items not associated with the user 123:
DB::table('items')->leftJoin(
'item_user', function ($join) {
$join->on('items.id', '=', 'item_user.item_id')
->where('item_user.user_id', '=', 123);
})
->whereNull('item_user.item_id')
->get();
this should work for you
$someuser = Auth::user();
$someusers_items = $someuser->related()->lists('item_id');
$all_items = Item::all()->lists('id');
$someuser_doesnt_have_items = array_diff($all_items, $someusers_items);
Ended up writing a scope for this like so:
public function scopeAvail($query)
{
return $query->join('item_user', 'items.id', '<>', 'item_user.item_id')->where('item_user.user_id', Auth::user()->id);
}
And then call:
Items::avail()->get();
Works for now, but a bit messy. Would like to see something with a keyword like not:
Auth::user()->itemsNot();
Basically Eloquent is running the above query anyway, except with a = instead of a <>.
Maybe you can use:
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
Source: http://laravel.com/docs/4.2/queries#advanced-wheres
This code brings the items that have no relationship with the user.
$items = $this->item->whereDoesntHave('users')->get();

advanced where clause fails

I am trying to get the records from a database where players have either played as player 1 or 2 in a game to calculate the gross profit for a player on a profile. I have the following Advanced Eloquent code:
$user = User::with('profile')->where('name', $username)->first();
$user_id = $user->id;
$games_model = Games::where(function ($q) {
global $user_id;
$q->where('player1', '=', $user_id)->orWhere('player2', '=', $user_id);
});
$games = $games_model->limit(3)->get();
// get gross profits
$gross_profits = $games_model->sum('bet');
dd($games_model->get()->toArray());
But when I try to take a look at the results dumped, I see a blank array. I am sure my user's ID is set correctly. The funny thing is it was only returning one result before instead of all the resulkts in the database. I'm confused. Thanks for the help in advance!
Something like this should work, assuming the database and naming conventions are follow.
Users::class
public function games()
{
return $this->hasMany(Games::class);
}
Query:
Users::where('name', $username)
->has('games')
->with('profile')
->limit(3)
->get();
Haven't tested but this should give you an idea.
here's the solution.
global dosen't work every time depending on variable scope. I changed
$games_model = Games::where(function ($q) {
global $user_id;
$q->where('player1', '=', $user_id)->orWhere('player2', '=', $user_id);
});
to
$user_id = $user->id;
$games_model = Games::where(function ($q) use ($user_id) {
$q->where('player1', '=', $user_id)->orWhere('player2', '=', $user_id);
});
and it works perfectly every time.

Laravel shows database row for test but not for other strings

I have actually no idea how I can fix this problem. I have tried quite a lot, so here is what I got:
I want to do a search function which checks different tables and different informations. Somehow I do only get results which I am directly related to (user_id in team table, the team I am in or my own username). My code looks like this:
public function search($param)
{
$result = ['users' => [], 'teams' => []];
$usersBySteamid = User::where('steamid', $param)->get();
$usersByName = User::where('username', 'LIKE', '%'.$param.'%')->get();
$teamsByName = Team::where('name', 'LIKE', '%'.$param.'%')->get();
$users = $usersBySteamid->merge($usersByName);
$result['users'] = $users;
$result['teams'] = $teamsByName;
return response()->json($result);
}
As a result I DO get my own username AND my own team, but not any other team or user.
Route:
Route::get('/admin/search/{param}', 'AdminController#search')->name('admin.search');
As a side information: I am using the auth middleware, but it did not make any problem until now, so I guess it might be irrelevant.

Laravel Model get all where $id = Auth::user()->id

How to List all rows from a DB where $id matches the logged user id.
I'm using default Auth from Laravel.
At the moment i can list them all with this method in my controller:
public function index(){
$invoices = Invoice::all();
return view('index', compact('invoices'));
}
But i just want the ones that are from this user which is logged in:
Something like
$invoices = Invoice::where('id', '=', Auth::user()->id);
Your code Seems almost right. I would do:
$invoice = Invoice::where('id', Auth::user()->id)->get();
So basically use the get in order to fetch a collection. And maybe I would separate the user id in a varaible in case that you change the authentication in the future ;)
When using any condition then of course you must need to add the get() method. Otherwise, you can't show your data.
$invoices = Invoice::where('id', '=', Auth::user()->id)->get();
This means that you want to see data on which user is logged in now

Categories