Search users that follow user with eloquent - laravel

I got one page in table pages with:
id = 1, name, lastname
I got the table followers with these fields:
page_id, follower_id
And I got the table users, with these fields:
id, name, lastname, photo, friendly_url
I got 'search', what the user write, and the $id of the page:
public function u_followers_search($id) {
$_POST['search']
}
I want to search all the users that follow the page with the $_POST['search'] and show these users...

Followers::select('users.*')
->leftJoin('users', 'followers.follower_id', '==', 'user.id')
->where('page.id', $id )
->get();
Assuming your follower id is user.id (foreign key relation between followers table and users table).

With laravel elequent.
//Page.php
public function users()
{
return $this->hasManyThrough(
'App\User',
'App\Follower', // followers model
'page_id', // Foreign key in Follower
'id', // Foreign key in Users
'id', // Local key Page
'follower_id' // Local key Users
);
}
//Controller
public function u_followers_search(Request $request) {
$page = Page::find($request->id);
return $page->load([
'users' => function($query) use ($request){
$query->where('name', 'LIKE', '%'.$request->search.'%')
->orWhere('lastname', 'LIKE', '%'.$request->search.'%');
}
]);
}
Source: https://laravel.com/docs/5.6/eloquent-relationships#has-many-through

Related

Laravel 9. Why does specifying a column limit for a related table not work?

I need get specify columns of the relationship. But both recomended in documentation way don't work for me.
I can do this by specifying the desired columns in the model, but I don't want to do it: maybe in the future I will need this relationship elsewhere with more (or fewer) columns.
Data base: table Author (id, name) and Article (id, title, author_id)
The author_id column is foreign key for id column of Author table.
Controller:
//it display all columns
$pack = Author::with(['Article' => function ($query) {
$query->select('id', 'title');
}])
->where('id', $id)
->get();
//also it display all columns
$pack = Author::query()
->with(['Article' => function ($query) {
$query->select('id', 'title');
}])
->where('id', $id)
->get()
//also it display all columns
$pack = Author::with(['Article:id,title'])
->where('id', $id)
->get();
Model:
class Author extends Model
{
protected $guarded = [];
public function Article()
{
return $this->hasMany('App\Models\Article')
//->select('id', 'title'); //If uncommented, then specifying columns works
;
}
}
Why doesn't specifying columns in the controller work for me?

How to retrieve data from two table in Laravel Eloquent

I have two DB tables.
education_institutions
id institution_name country city logo description
1 ABC College UK London null null
user_educations
id user_id institution_id grade year
1 1 1 3.2 2010
Relationships with both models are
UserEducation
public function educationInstitution()
{
return $this->hasMany(EducationInstitution::class,'institution_id');
}
EducationInstitution
public function userEducation()
{
return $this->belongsTo(UserEducation::class,'institution_id');
}
Now how can I retrieve all education institutions of a particular user with the institution details from educations_institution table.
I tried something like
public function getUserEducation()
{
$userEducation = auth()->user()->userEducation()
->orderBy('created_at', 'desc')
->get();
return response()->json([
'userEducation' => $userEducation
]);
}
But it retrieves only education institution id like:
I need user educations with corresponding institution details.
You can use with() function for relationship selection.
public function getUserEducation()
{
$userEducation = UserEducation::with('educationInstitution')->where('user_id',auth()->user()->id)
->orderBy('created_at', 'desc')
->get();
return response()->json([
'userEducation' => $userEducation
]);
}

Laravel 5.2 Eloquent ORM to get data from 3 tables

I have the following tables. users, user_details and client_teams. Each user has one details and each user can have many teams. schema for users:
id, name, email,parent_user_id
user_details:
id, user_id, client_team_id
client_teams:
id, user_id, team_name,status
In user_model i have the following relations:
public function userDetails(){
return $this->belongsTo('App\Models\UserDetails','id','user_id');
}
public function clientTeamList(){
return $this->hasMany('App\Models\ClientTeams','user_id','id');
}
In user_details model i have the following relation:
public function clientMemberTeam(){
return $this->belongsTo('App\Models\ClientTeams','client_team_id');
}
I want to be show the list of users who have a specific team ID and created by a specific user. The query that i am using is this:
$userCollections=Users::where([
['users.status','!=','DELETE'],
['users.parent_user_id',$clientId],
['users.id','!=',$loginUser->id]
])
->with([
'userDetails'=>function($query) {
$query->where('client_team_id',1);
}
]);
This is giving me all records for this user, Whereas i want to match by client_team_id and user_id
You need to use whereHas and orWhereHas methods to put "where" conditions on your has queries.
Please look into https://laravel.com/docs/8.x/eloquent-relationships
$userCollections = Users::where([['users.status', '!=', 'DELETE'],
['users.parent_user_id', $clientId],['users.id', '!=', $loginUser->id]
])
->whereHas('userDetails' => function ($query) {
$query->where('client_team_id', 1);
})->get();

How can I get records created_by user with role

Hi I have a table "fiches" with the user_id who created the record.
All my users have a role_id.
How can I get all "fiches" where user_id has the role of 'admin' or something else.
User.php
class User extends Authenticatable{
public function role()
{
return $this->belongsTo(Role::class);
}
// Fiches of User
public function fiches()
{
return $this->hasMany(Fiche::class);
}
}
Fiche.php
class Fiche extends Model{
public function user()
{
return $this->belongsTo('App\User');
}
}
My Query
$fiches = Fiche::whereDay('created_at', '=', date('d'))->where('status', '=', 'A Ecouter')->pluck('id')->count();
Fiches table (id, user_id, name, status, created_at)
Users table (id, role_id, name, created_at)
I want to have the Fiches that was created by role == Admin
You need to use whereHas with nested relationship. Assuming your roles table has column type the code will look like:
$fiches = Fiche::whereHas('user.role', function ($query) {
$query->where('type', 'admin');
})->get();
This query will retrieve all fiches that have users with role that has column 'type' of value 'admin'.
Edit:
For your specific case you provided in the comment the query should look like this:
$fichesAEcouterJours = Fiche::whereDay('created_at', '=', date('d'))
->where(function ($query) {
$query->where('status', '=', 'A Ecouter')
->orWhere('status', '=', 'A Reporter');
})
->whereHas('user.role', function($query){
$query->where('name', 'agent');
})
->count();
Or you can use ->whereIn('status', ['A Ecouter', 'A Reporter']) instead. Note that there is no need to call ->get() before ->count() in this case - it's faster to let Eloquent generate SELECT COUNT query than it is to ->get() collection of all rows and call ->count() of that collection.

Laravel: get data from variouos tables based on optional conditions

I want to write a query based on optional condition that will fetch data from different tables. My schema looks like
myboxes Table
id,
type_id --> foreign key to box_type table
postal_code
po_box
created_at
updated_at
mybox_access table
id
mybox_id -> foreign key to myboxes table
email
box_type table
id
type_name
And here are my models
MyBox.php
class MyBox extends Model {
public function type() {
return this->hasOne(BoxType::class, 'id', 'type_id');
}
public function access() id
return this->hasOne(MyBoxAccess::class, 'mybox_id', 'type_id');
}
}
MyBoxType.php has following relation ship
public function mybox() {
return this->hasOne(MyBox::class, 'id', 'type_id');
}
And MyBoxAccess.php has following relationship
public function vbox() {
return $this->belongsTo(MyBox::class, 'id', 'mybox_id');
}
Now I want to get based on following condition
I have email as required param and postal_code and po_box as optional params (but one of them will be must and both can also be present).
So I want to get data of all my_boxes that have type_id 3 OR all myboxes whoes id matches to email in mybox_access table AND postal_code or po_box matches to params in myboxes table
For simple match of params postal code and po_box I can write some thing like
$result = new MyBox();
if(!empty($request['postal_code'])) {
$result->where('postal_code', like, '%'.$request['postal_code']);
}
if(!empty($request['po_box'])) {
$result->where('po_box', like, '%'.$request['po_box']);
}
$result = $result->get();
But I don't know how to get data for above mentioned condition. When I try to do using with() like
MyBox::with(['access' => function(Builder $query) use ($request){
$query->where('mybox_id',$request['id']);
}])->get();
I get
`Argument 1 Passed to {closure} () must be an instance of Illuminat\Database\Query\Builder, instance of Illuminate\Databaase\Eloquent\Relation\HasOne given`
Can any body please let me know how can I get data based on above mentioned condition
$query is a relationship, not a builder instance.
So this should not throw any Exception.
MyBox::with(['access' => function ($query) {
$query->where('mybox_id', $request['id']);
}])->get();
But I don't think it'd resole your issue because your Box <=> Access relationship is not right. It should be HasMany.
// MyBox.php
public function type()
{
return $this->hasOne(BoxType::class, 'id', 'type_id');
}
public function access()
{
return $this->hasMany(MyBoxAccess::class, 'mybox_id', 'id');
}
Then in your Controller you could do this.
// $results where type_id is 3
$results = MyBox::where('type_id', 3)->get();
// List of boxes accessible by email
$results = MyBox::whereHas('access', function ($query) {
$query->where('email', request()->input('email'));
})->get();
// Results where postal_code and po_box matches the request
$results = MyBox::with('access')->where(function ($query) {
if (request()->has('postal_code')) {
$query->where('postal_code', 'like', '%' . request()->input('postal_code'));
}
if (request()->has('po_box')) {
$query->where('po_box', 'like', '%' . request()->input('po_box'));
}
})->get();
And if you want to merge all conditions:
$results = MyBox::where(function ($query) {
if (request()->has('type_id')) {
$query->where('type_id', request()->input('type_id'));
}
if (request()->has('email')) {
$query->whereHas('access', function ($query) {
$query->where('email', request()->input('email'));
});
}
if (request()->has('postal_code')) {
$query->where('postal_code', 'like', '%' . request()->input('postal_code'));
}
if (request()->has('po_box')) {
$query->where('po_box', 'like', '%' . request()->input('po_box'));
}
})->get();
I always use the request() facade when using in closures, it feels cleaner to me.
Try this query:
MyBox::with('access')->get();

Resources