SQLSTATE[23000]: Integrity constraint violation: 1052. Laravel eloquent issue when joining table - php

I have News table and the column in the blade table posted by is empty but in my news table the column users_id which is the posted by has a users_id value. I cant get the user who posted the specific news in specific school. I already have a working query for the news, but the problem is i cant join the users table where the name of the user who posted the news is in there. Can someone know what are the problem of my query? Help will be appreciated. Thanks
Index controller
public function index()
{
//testing query that returns an error
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('school_id', Auth::user()->school_id)->get();
//the query that i want still returns an error because of the auth
$postedby = DB::select(
"SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = 'Auth::user()->school_id'");
//working queries and i dont know how to convert the $postedby query join to eloquent.
if (Auth::user()->role == 0) {
$news = Newsboard::where('active','=',1)->get();
} elseif (Auth::user()->role == 1 || Auth::user()->role == 5) {
$news = Newsboard::where('school_id', '=', Auth::user()->school_id )
->where('active','=',1)
->get();
} else {
$role = Auth::user()->role;
$news = Newsboard::where('school_id', '=', Auth::user()->school_id )
->where('status', '=', 1)
->where('active','=',1)
->whereRaw("group_id in('$role', '0')")
->get();
}
dd($userschool);
return view('admin.pages.news.index', [
'page_title' => $this->page_title,
'news' => $news,
'mnuname' => 'News',
]);
}

Set your Auth::user()->school_id as variable
$school_id = Auth::user()->school_id;
//the query that i want still returns an error because of the auth
$postedby = DB::select(
"SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = '$school_id'");
Or this:
Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where(['news.school_id' => $school_id])->get();

Because both users and news table contain school_id column, so in where condition must has table prefix.
Please try:
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('news.school_id', Auth::user()->school_id)->get();
//or
//the query that i want still returns an error because of the auth
$postedby = DB::select("SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = '".Auth::user()->school_id."'");

$school_id = Auth::user()->school_id;
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('school_id', $school_id)->get();

Related

Convert mysql query into Eloquent laravel query

I am trying to make the following query in laravel:
SELECT a.name AS subname, a.area_id, b.name, u. id, u.lawyer_id,u.active_search,
FROM subarea a
LEFT JOIN user_subarea u ON u.subarea_id = a.id
AND u.user_id = ?
LEFT JOIN branch b ON a.area_id = b.id
The idea is to obtain the subareas and see if the search is activated by the user.
The user_subarea table might have a record that matches the id of the subarea table where the active_search is equal to 0 or 1. If it doesn't exist I would like the query to return null.
While I was able to achieve this in raw SQL when I try the same with eloquent in Laravel I am not returning any value. I have done the following:
$query = DB::table('subarea')
->join('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Any help will be much appreciated.
I found by myself the answer it was just to add a lefjoin in the first join. It is not in the laravel docs but works too.
$query = DB::table('subarea')
->lefjoin('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Try this one, If you get a problem, please comment.
$value = \Auth::user()->id;
$query = DB::table('subarea')
->where('user_subarea.user_id', '=',$value)
->leftJoin('user_subarea', 'subarea.id', '=', 'user_subarea.subarea_id')
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('subarea.name AS subname','subarea.area_id', 'branch.name', 'user_subarea.id','user_subarea.lawyer_id','user_subarea.active_search')
->get();

How to return highest id value from a table via join with eloquent Laravel 5.2

i have two tables that share a relationship users and log table. I’m trying to query the users table and get the record from log with the highest id value
so far this is what I have that’s returning duplicate entries:
$students = User::with([
'course' => function ($query) {
$query->get(['id', 'name']);
}
])
->join('log', 'users.id', '=', 'log.user_id')
->where('log.event', 1)
->orderBy('log.id', 'desc')
->where('users.verified', 1)
->get(['users.*', 'log.id AS logid']);
Ideally, I want the last inserted record from the log table for each user
groupBy('user_id')
returns the first record
$students = User::with([
'course' => function ($query) {
$query->get(['id', 'name']);
}
])
->join('log', 'users.id', '=', 'log.user_id')
->where('log.event', 1)
->whereRaw('log.id = (select max(`id`) from log where `user_id` = users.id )')
->where('users.verified', 1)
->get(['users.*', 'log.id AS logid', 'log.user_id']);
I think you are very close to, only you need to use limit.
->where('users.verified', 1)
->take(1) // add this to get only a single record
->get(['users.*', 'log.id AS logid']);
Try the below solution with 1 more where condition without groupBy
$students = User::with([
'course' => function ($query) {
$query->get(['id', 'name']);
}
])
->join('log', 'users.id', '=', 'log.user_id')
->where('log.event', 1)
->orderBy('log.id', 'desc')
->where('users.verified', 1)
->where('log.id',DB::raw("SELECT MAX(id) FROM log WHERE log.user_id = users.id")) // get the max id value
->get(['users.*', 'log.id AS logid']);

Very slow eloquent query

I have a query in one of my controller in my Laravel controllers that looks like this,
$project = new Project;
$me = ResourceServer::getOwnerId();
$my_projects = Project::ManagedByMe($me)
->OwnedByOrganisationIAmIn($me)
->IAmACollaborator($me)
->NoArchived()
->get(array(
'projects.id',
'projects.name',
'projects.description',
'projects.total_cost',
'projects.sales_person',
'projects.slug',
'projects.uri_hash',
'projects.client_id',
'projects.start_date',
'projects.finish_date',
'projects.organisation_id',
'projects.locked_by',
'projects.created_at',
'projects.status',
'projects.owner_id',
'projects.user_id',
'projects.archived_at'
));
$my_projects->load('projectmanager');
$my_projects->load('clients');
$my_projects->load('organisations')->load('organisations.users');
$my_projects->load('collaborators');
$my_projects->load('status');
$my_projects->load('notifications')->load('notifications.user');
$my_projects->load(array('projectview'=>function($query){
$query->where('users.id','=',ResourceServer::getOwnerId());
})); 
It returns 898 rows of data, and takes over a minute to execute. I am using scopes in the query, that look like this,
public function scopeManagedByMe($query, $user_id) {
$query->distinct();
$query->leftJoin('project_managers', 'projects.id', '=', 'project_managers.project_id');
$query->where('project_managers.user_id', '=', $user_id);
}
public function scopeOwnedByOrganisationIAmIn($query, $user_id) {
$query->leftJoin('organisations', 'projects.organisation_id', '=', 'organisations.id');
$query->leftJoin('organisation_user', 'organisations.id', '=', 'organisation_user.organisation_id');
$query->orWhere('organisation_user.user_id', '=', $user_id);
}
public function scopeIAmACollaborator($query, $user_id) {
$query->leftJoin('collaborators', 'projects.id', '=', 'collaborators.project_id');
$query->orWhere('collaborators.user_id', '=', $user_id);
}
public function scopeNoArchived($query) {
$query->orWhere('projects.archived_at', '=', '0000-00-00 00:00:00');
$query->whereNull('projects.deleted_at');
}
and the SQL that is actually run looks like this,
select distinct `projects`.`id`,
`projects`.`name`,
`projects`.`description`,
`projects`.`total_cost`,
`projects`.`sales_person`,
`projects`.`slug`, `projects`.`uri_hash`,
`projects`.`client_id`,
`projects`.`start_date`, `projects`.`finish_date`,
`projects`.`organisation_id`,
`projects`.`locked_by`, `projects`.`created_at`,
`projects`.`status`,
`projects`.`owner_id`,
`projects`.`user_id`,
`projects`.`archived_at`
from `projects`
left join `project_managers` on `projects`.`id` = `project_managers`.`project_id`
left join `organisations` on `projects`.`organisation_id` = `organisations`.`id`
left join `organisation_user` on `organisations`.`id` = `organisation_user`.`organisation_id`
left join `collaborators` on `projects`.`id` = `collaborators`.`project_id`
where `projects`.`deleted_at` is null
and `project_managers`.`user_id` = ? or `organisation_user`.`user_id` = ?
or `collaborators`.`user_id` = ? or `projects`.`archived_at` = ?
and `projects`.`deleted_at` is null
What I am trying to do, is select all the projects that I belong to, either by virtue that I am in an organisation that owns a project, I am project manager of the project or a collaborator of the project.
At first set indexes on join-condition fields:
`projects`.`id`
`projects`.`organisation_id`
`project_managers`.`project_id`
`organisations`.`id`
`organisation_user`.`organisation_id`
`collaborators`.`project_id`
if some of them are not setted.
Then update your query execution time in question subject.

How would I code this MySQL query in Laravel Eloquent?

I'm trying to work with a semi-complex query (by my standards, anyway) but I can't think how to do it using the query builder or using eloquent relationships.
My relationships table is: user_id_1 | user_id_2 | status | action_user_id in the case of friends, action_user_id can be ignored and status = 1. There is only one row per relationship so if you want to select all relationships that belong to User 17 then you need to check both user_id_1 and user_id_2 because the id could be in either column. I followed the database structure from here: http://www.codedodle.com/2015/03/social-network-friends-relationship.html
The sort of query I'm trying to perform is:
SELECT users.*
FROM users
LEFT JOIN users_relationships AS r
ON (
users.id = r.user_id_1
AND r.user_id_1 != $user_id
) OR (
users.id = r.user_id_2
AND r.user_id_2 != $user_id
)
WHERE r.status = 1
AND (
r.user_id_1 = $user_id
OR r.user_id_2 = $user_id
)
Such a thing would be best in an eloquent relationship so it would be easy to perform: $user->friends and it would return the results of the above but I'm stuck in all directions.
My best attempt unfortunately not using relationship is this:
User::with('profile')->join('user_relationships as r', function($join) use ($user_id) {
$join->on(DB::raw('( users.id = r.user_id_1 AND r.user_id_1 != ? )', [$user_id]), DB::raw(''), DB::raw(''));
$join->orOn(DB::raw('( users.id = r.user_id_2 AND r.user_id_2 != ? )', [$user_id]), DB::raw(''), DB::raw(''));
})
->where('r.status', 1)
->where(function($query) use ($user_id) {
$query->where('r.user_id_1', $user_id)
->orWhere('r.user_id_2', $user_id);
})
->get(['users.*']);
This however gives me errors relating to the parameters:
SQLSTATE[HY093]: Invalid parameter number (SQL: select `users`.* from `users` inner join `user_relationships` as `r` on ( users.id = r.user_id_1 AND r.user_id_1 != 1 ) or ( users.id = r.user_id_2 AND r.user_id_2 != 30 ) where `users`.`deleted_at` is null and `r`.`status` = 30 and (`r`.`user_id_1` = ? or `r`.`user_id_2` = ?))
I'm not sure how to do what I want to do.
The problem is here:
DB::raw('( users.id = r.user_id_1 AND r.user_id_1 != ? )', [$user_id])
DB::raw() doesn't take a second parameter for bindings. Use ->on()->where() instead (thanks to user4621032):
->leftJoin('users_relationships AS r', function($join) use($user_id) {
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
So to setup your ->friends() function as desired, you can use:
public function friends()
{
$user_id = $this->id;
return self::with('profile')
->leftJoin('users_relationships AS r', function($join) use($user_id) {
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
->where('r.status', 1)
->where(function($query) use ($user_id) {
$query->where('r.user_id_1', $user_id)
->orWhere('r.user_id_2', $user_id);
})
->get(['users.*']);
}
might be like this
DB::table('users')
->leftJoin('users_relationships AS r', function($join) use($user_id){
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
->where('r.status',1)
->where('r.user_id_1','=',$user_id)
->orWhere('r.user_id_2','=',$user_id)
->get();

laravel sql queries not working after conversion from regular sql

I was wondering if you could look at 3 sql queries followed by the converted JOIN queries that do not work. I keep getting an undefined index error - not sure what i'm doing wrong.
Please note that $db_table_prefix = app_ No big deal.
$db->sql_escape = mysql_real_escape_string (removed b/c laravel does it's own escaping)
1:
OLD:
$sql = "SELECT ".$db_table_prefix."Users.Group_ID,
".$db_table_prefix."Groups.*
FROM ".$db_table_prefix."Users
INNER JOIN ".$db_table_prefix."Groups ON ".$db_table_prefix."Users.Group_ID = ".$db_table_prefix."Groups.Group_ID
WHERE
User_ID = '".$db->sql_escape($this->user_id)."'";
NEW:
return (array)DB::table('app_Users')
->select('app_Users.Group_ID')
->join('app_Groups', 'app_Users.Group_ID', '=', 'app_Groups.Group_ID')
->where('User_ID', '=', $this->user_id)
->first();
2:
Old:
$sql = "SELECT ".$db_table_prefix."Users.Group_ID,
".$db_table_prefix."Groups.* FROM ".$db_table_prefix."Users
INNER JOIN ".$db_table_prefix."Groups ON ".$db_table_prefix."Users.Group_ID = ".$db_table_prefix."Groups.Group_ID
WHERE User_ID = '".$db->sql_escape($this->user_id)."'
AND
".$db_table_prefix."Users.Group_ID = '".$db->sql_escape($db->sql_escape($id))."'
LIMIT 1
";
New:
return (bool)DB::table('app_Users')
->select('app_Users.Group_ID')
->join('app_Groups', 'app_Users.Group_ID', '=', 'app_Groups.Group_ID')
->where('User_ID', '=', $this->user_id)
->where('app_Users.Group_ID', '=', $id)
->first();
3.
Old:
$sql = "SELECT ".$db_table_prefix."Users.Group_ID,
".$db_table_prefix."Groups.*
FROM ".$db_table_prefix."Users
INNER JOIN ".$db_table_prefix."Groups ON ".$db_table_prefix."Users.Group_ID = ".$db_table_prefix."Groups.Group_ID
WHERE
User_ID = '".$db->sql_escape($userId)."'";
New:
return (array) DB::table('app_Users')
->select('app_Users.Group_ID')
->join('app_Groups', 'app_Users.Group_ID', '=', 'app_Groups.Group_ID')
->where('User_ID', '=', $userId)
->first();
Thanks!

Categories