How to make a query when have array - php

I have three tables: client, project and client_project.
I want to show in a view all the projects of one client.
Here is the explained code:
<?php
public function editClient($id)
{
$client = Client::find($id);
// I get an array with client_id and project_id of the clients
// which is the same I pass in the URL.
$client_project = DB::table('client_project')->where('client_id',$id)->get();
// return view('cms.public.views.clients.editclient')->withClient($client);
}
Now I want to show the name of projects when the field id of table projects have the same value of project_id in $client_project array.
Here is the example of how to do it if it's only one value, maybe can help.
public function editClient($id)
{
$client = Client::find($id);
$client_project = DB::table('client_project')->where('client_id',$id)->first()->project_id;
$project = DB::table('projects')->where('id',$client_project)->first();
return $project;
}

Use One to Many relationship.
In Client.php Model
public function projects()
{
return $this->belongsTo('App\Project', 'client_id');
}
And in your Project.php Model
public function client()
{
return $this->hasMany('App\Client', 'client_id');
}
Now call
$client_project = Client::find($id)->projects;
You will get details here https://laravel.com/docs/5.5/eloquent-relationships#one-to-many

Instead of taking the first() client project, take them all and use the whereIn() method in project selection.
$projects = DB::table('projects')->whereIn('id', function ($query) {
$query->select('project_id')->from('client_project')->where('client_id', $id);
})->get();
Here's the laravel documentation link: Laravel 5.5 Documentation - Queries#where-clauses
I'm answering on what I've understood about your request which is not very clear.

Related

I want to get the related client name through a hasManyThrough relationship

I need to print on the view the name of the client that refers to the tasks of its projects through the interim relationship called projects.
I used a hasManyThrough relationship because I needed to get more information. Now I need to get the client name as described above.
Relationship defined in the Client model:
public function projects()
{
return $this->hasMany(Project::class);
}
public function tasks()
{
return $this->hasManyThrough(Task::class, Project::class);
}
Relationship defined in the Project model:
public function client()
{
return $this->belongsTo(Client::class);
}
public function tasks()
{
return $this->hasMany(Task::class);
}
Relationship defined in the Task model:
public function project()
{
return $this->belongsTo(Project::class);
}
I've tried this but can't get the client name
TaskController:
public function index($id = NULL)
{
$tasks = Task::all();
$project = Project::find($id)->load(['tasks']);
return view('task.index', compact('tasks','project'));
}
In the task view of that task I want to see the following line:
"List of tasks related projects to (client name)"
Anyone who can kindly help me?
clients
id - integer
name - string
projects
id - integer
client_id - integer
name - string
tasks
id - integer
project_id - integer
title - string
If I understood correctly, you need first to add a relationship on Task model:
public function client()
{
return $this->hasOneThrough(Client::class, Project::class);
}
this relationship will allow you to get the client to whom the project containing this task belongs to.
Then on your TaskController :
public function index($id = NULL)
{
$tasks = Task::with(['project', 'client'])->get();
$project = Project::find($id)->load(['tasks']);
return view('task.index', compact('tasks','project'));
}
Now the $tasks will have within them the project info + client info

how to make consultation with three tables in Eloquent Laravel

I have three tables that are the following users, mapas, marcadores
A user has several mapas
a mapa has several marcadores
What I'm trying to do is show the marcadores that belong to the mapas of the user who has logged in.
this are the tables and relationship
This is the function in the controller that I am working on:
public function index()
{
$mapas = Mapa::orderBy('id', 'DESC')->where('user_id', auth()->user()->id);
$marcadores = Marcador::orderBy('id', 'DESC')->where('mapa_id');
return view('user.marcadores.index', compact('marcadores'));
}
thanks for your help
You are trying to get all the mapas id first and then filter marcadores according to those id's. Try using the code below for that:
public function index()
{
$mapas = Mapa::orderBy('id', 'DESC')->where('user_id', auth()->user()->id)->pluck('id')->toArray();
$marcadores = Marcador::orderBy('id', 'DESC')->whereIn('mapa_id', $mapas)->get();
return view('user.marcadores.index', compact('marcadores'));
}
You can use JOINS for this. Try the next code (maybe the syntax is not the correct one, but take the idea):
public function index()
{
$marks = DB::table('mapas')
->join('marcadores', 'marcadores.mapa_id', '=', 'mapas.id')
->where('mapas.user_id', auth()->user()->id)
->select('marcadores.*')
->orderBy('marcadores.id', 'DESC')
->get();
return view('user.marcadores.index', compact('marks'));
}
The easiest and Laravel standard way to do this is create a hasManyThrough relationship from User to Marcadores
UserModel
class User extends Model
{
public function marcadores()
{
return $this->hasManyThrough(Marcadores::class, Mapas::class);
}
}
Controller
public function index()
{
$marcadores = auth()->user()->marcadores;
return view('user.marcadores.index', ['marcadores' => $marcadores]);
}

Laravel Pagination

How can I create a pagination in laravel?
My Model
Post
function comments() {
return $this->hasMany('Comment')
->orderBy('created_at', 'desc');
}
Comment
function posts(){
return $this->belongsTo('Post');
}
User
function posts(){
return $this->hasMany('Post');
}
function comments(){
return $this->hasMany('Comment');
}
UserController
$user = User::find(1); //this will give me all the user's post and comment details
//i know I can do $user = User::paginate(30) to get 30 user per page
What I want to Achieve
I want to create a pagination of 10 comment per page.
Thanks for your help in advance.
You have two options: you can call paginate() on the relationship query, or you can manually create a paginator.
Call paginate() on the relationship query (uses the relationship function):
$user = User::find(1);
$comments = $user->comments()->paginate(10);
Manually create a paginator (uses the relationship attribute):
$user = User::find(1);
$paginator = Paginator::make($user->comments, $user->comments->count(), 10);
Pagination documentation can be found here.
Try this,
$only10comments = User::with('comments')->paginate(10);
If you use next, previous links in pagination, then use simplePaginate.
$only10comments = User::with('comments')->simplePaginate(10);
Hope this helps.

laravel 4 how to order and join by eloquent

Im new in Laravel 4, and right now im coding for small project, i use laravel as framework to build my website, but my code i always wonder it's optimize or not because in my model i just wrote:
Category Model
public function parents()
{
return $this->belongsTo('Category', 'cat_father');
}
public function children()
{
return $this->hasMany('Category', 'cat_father');
}
}
Post Model:
<?php
class Post extends BaseModel{
public $table = "post";
protected $primaryKey = 'idpost';
public function Category()
{
return $this->belongsTo('Category', 'cat_id');
}
}
because i didn't know how to join 2 tables in laravel 4, i have a condition is find all post from my categories, which it hadn't belong to category name "Reunion", but i didn't know how to do that, therefore i wrote 2 lines code for that purpose (im not sure wrote code in controller is best way but i didn't know how to call method from Model to controller and get return value)
My method from controller for select all post, it hasn't belong to category name "Reunion"
public function getAllPostView()
{
$getCat = Category::where('cat_name','=', 'Reunion')->firstOrFail();
$post = Post::where('cat_id', '!=', $getCat->idcategory)->get();
return View::make('layouts.post')->with('post',$post);
}
My question, my code is optimize when i wrote it in controller? and how to wrote it in model and get parameter for passing it to controller and use it to view.
second question is how to order "POST" because some cases post need to be ordered from new to old
This is how you do it:
$exclude = 'Reunion';
$posts = Post::select('posts.*')->join('categories', function ($j) use ($exclude) {
$j->on('posts.cat_id', '=', 'categories.idcategory')
->where('categories.name', '<>', $exclude);
})->get();
could just use simple joins
public function getAllPostView()
{
$getCat = Category::where('cat_name','=', 'Reunion')
->join('post','post.cat_id', '!=','Category.idcategory')->get();
return View::make('layouts.post')->with('post',$post);
}
Look out for same field names in both the tables if so can use select
$getCat = Category::select('Category.idcategory as cat_id','Category.cat_id as pos_id','many other fields')
// 'as cat_id' not required for unique field names
->join('post','post.cat_id', '!=','Category.idcategory')
->where('cat_name','=', 'Reunion')
->get();

Laravel filtering hasMany results

I have three tables - Campaigns, Actions and Activists. A Campaign has many Actions, and an Action belongs to both an Activist and a Campaign.
Each action has a client_id (from the client_id of the campaign it belongs to), so when a client views a list of activists, they should only see those who have taken an action on one of their campaigns.
Likewise, when viewing an individual activist, they should only see those actions related to their campaigns.
Models
Campaign.php
public function actions()
{
return $this->hasMany('Action');
}
Action.php
public function campaign()
{
return $this->belongsTo('Campaign', 'campaign_id');
}
public function activist()
{
return $this->belongsTo('Activist', 'activist_id');
}
Activists.php
public function actions()
{
return $this->hasMany('Action');
}
Controllers
ActivistsController.php
public function index()
{
$activists = Activist::with('actions')->whereHas('actions', function($q) {
$user = Sentry::getUser();
$q->where('client_id', $user->client_id);
}))->get();
foreach ($activists as $activist)
{
$activist->total = $activist->actions()->count();
}
}
public function getActivist($id)
{
$activist = Activist::with('actions')->whereHas('actions', function($q) {
$user = Sentry::getUser();
$q->where('client_id', $user->client_id);
})->find($id);
$activist->total = $activist->actions()->count();
}
I'm seeing the following:
On the /activists page, I'm correctly seeing only those activists who have taken an action related to my client_id, but also every action they've taken. Likewise, count() returns a full count of all the activists' actions.
On the /activists/{id} page, it correctly returns null if the activist hasn't taken any actions related to my client_id, but where they have, I again see all of their actions and a full count.
AFL. There's something blinding obvious I'm missing, right?
Thanks.
[edit] Updated to add:
Using the client_id filter on both with and whereHas rectifies the 'all actions appearing regardless' issue, but the count issue remains (and I'm not sure this is remotely the right way to improve this):
ActivistController.php
public function index()
{
$filter = function($q) {
$user = Sentry::getUser();
$q->where('client_id', $user->client_id);
};
$activists = Activist::with(array('actions' => $filter))
->whereHas('actions', $filter)
->get();
}
public function getActivist($id)
{
$filter = function($q) {
$user = Sentry::getUser();
$q->where('client_id', $user->client_id);
};
$activist = Activist::with(array('actions' => $filter))
->whereHas('actions', $filter)
->find($id);
}
I've solved this now, but for reference:
$activist->actions()->count()
This, obviously in hindsight, ignores any of the prior queries and simply counts data returned from the actions() method as defined in the activist model.
I should have provided an alternate method in the model that includes the appropriate where function, like so:
public function actionsClient($id)
{
return $this->hasMany('Action')->where('client_id', $id);
}
Meaning the count could then be invoked with:
$activist->total = $activist->actionsClient($id)->count();
for a single campaign and
foreach ($activists as $activist)
{
$activist->total = $activist->actionsClient($activist->id)->count();
}
on the index. I'd previously tried this, but as described here - How to access model hasMany Relation with where condition? - relations must be described in camelCase (actions_client > actionsClient).
In my usage this worked for me:
$clients = Profile::select('id', 'name')->orderBy('initial')->whereHas('type', function ($query) {
$query->where('slug', 'client');
})->office()->pluck('name', 'id');
You already have the instance of $activist eager loading their actions, meaning you already know the actions of the activist beacause they are already in the instance, so why call actions() again instead of just doing this:
$activist->actions->count()

Categories