How to make Query between two tables in laravel - php

Hello I want to ask for how to make query in 2 tables to get the summary of value from table payments where type_id = id from types table and this is tables structure
this is the charts code
$chartـin_contract = Charts::create('bar', 'highcharts')
->title('My nice chart')
->labels($value_type->type)
->values([5,10])
->dimensions(0,500);
in labels i get the values from database but did't work with me
and this is the direct query
$value_type = DB::select('select type, value from payments,types where payments.`type_id` = types.id');
I want view the data that came from database in chart I am using laravel chart package

Please review Eloquent Relationships in the Laravel docs - https://laravel.com/docs/5.5/eloquent-relationships
The relationship between the two tables is defined (as in a one-to-one, one-to-many or many-to-many relationship) and then you will be able to query those relationships.

For this you need to establish the Relationship in tables.
NOTE: I am assuming that your task may have multiple payments
In your tasks model its one to many relation.
Task.php (Model add the following)
public function payments(){
return $this->hasMany(Payments::class);
}
And in your payments model its many to one relation.
Payments.php (Assuming)
public function task(){
return $this->belongsTo(Task::class);
}
Think now you want to get all the payments for a task. Let me show the eg: in command line
php artisan tinker
$task = App\Task::where('id',1)->get(); //Think that you have first task
$task->payments; //You can call the relation ship established condition function
Think you are browising for payment and want a task then
php artisan tinker
$payment = App\Payment::where('id',1)->get();//find the payment with id 1, just for the sake of example
$payment->task; //This will be the task() function that you have written int the model

Related

LARAVEL Eloquent: BelongsTo Relationship - Bulk update

Imagine I want to lend multiple books to a customer.
A customer can loan many books (hasMany) but a book can only be lend to one customer (BelongsTo).
I want to change the BelongsTo side of the relationship for multiple books in one go.
Laravel Documentation says to use the associate() function. But as far as I can see, that's for changing one object at a time. So I have to use a loop as in massLoanOne. This generates a lot of queries (n + 1).
Another way of doing this is by updating the customer_id on the Book model directly, as in massLoanTwo.
This generates only 2 queries. But this is not the proper Object Oriented way.
Is there a better way to update the BelongsTo side of this one-to-many (reverse) relationship bij using the Eloquent magic?
<?php
public function massLoanOne(MassLoanCustomerRequest $request)
{
foreach ($request->ids as $id) {
Book::find($id)->customer()->associate(Customer::find($request->customer_id))->save();
}
return response()->noContent();
}
public function massLoanTwo(MassLoanCustomerRequest $request)
{
Book::whereIn('id', request('ids'))->update(['customer_id' => $request->customer_id]);
return response()->noContent();
}
?>

Laravel Eloquent - Combining queries to single one using relations

I'm working on a project where I'm using Laravel Eloquent to fetch all my data from my database.
I'm storing basketball clubs, teams and players in different tables.
Now I want to select all basketball players that belong to a team that belongs to a club.
I created a relation in the Club model:
public function basketballPlayers()
{
return $this->hasManyThrough('App\Models\Basketball\BasketballPlayer','App\Models\Basketball\BasketballTeam','id','team_id');
}
And a user relation in the BasketballPlayer model:
public function user()
{
return $this->hasOne('App\User','id','user_id');
}
Now when I execute the following command, DB::getQueryLog() returns 3 Queries.
Club::findOrFail($club_id)->basketballPlayers()->with('user')->get();
But when I execute the following command without using relations, DB::getQueryLog() returns only 1 query.
$players = BasketballPlayer::Join('basketball_teams','basketball_teams.id','=','basketball_players.team_id')
->join('users','users.id','=','basketball_players.user_id')
->where('basketball_teams.club_id','=',$authUser->club_id)
->get(['basketball_players.*','users.firstname','users.lastname','basketball_teams.name']);
I don't need all the data from the club and the user (see ->get(...) in the Join query).
Is it possible to achieve the same result like in the "long" manual Join-query using the much cleaner and simpler Eloquent relation approach?
Thanks for your help!
You can read less data using with (not all user columns as example) by this
Club::findOrFail($club_id)
->basketballPlayers()
->with('user:id,firstname,lastname') // <- here is change
->get();
The id (and foreign keys) column is important. You should be also able to make nested with in following way (I write code from head - so please test it):
Club::findOrFail($club_id)
->with('BasketballPlayer:id,user_id')
->with('BasketballPlayer.user:id,firstname,lastname')
->get();

Laravel 5.4 Relationships between 3 tables

I am new in laravel, I already know how to join tables using the query builder. I just like to learn how to use relationships to avoid repetition of codes and to simplify it. I can join 2 tables, but I can't get the 3rd table.
I like to display employees assigned tasks information from the Tasks table, this table only has the project id that needs to be joined to the Projects table. Other employees can join in existing projects with other employees.
Employee model:
public function tasks()
{
return $this->hasMany('\App\Task', 'project_coder', 'id');
}
Task model:
public function projects()
{
return $this->hasMany('\App\Project', 'id', 'project_id');
}
Projects model:
public function belongsToTasks()
{
return $this->belongsToMany('\App\Task', 'project_id', 'id');
}
I can only get the IDS from Task model. the ID will be use to fetch the project info from project tables. Unfortunately I cant do that part.
Employees controller:
public function show($id)
{
$data = Employees::find($id);
return view('show-employee')->withInfo($data);
}
Is it good practice to use query builder rather than relationships?
UPDATE:
Employees table
{
"id":1,
"name": "Juan"
}
Tasks table
{
"id":1, // autoincrement and will not be use for linking to other tables.
"project_id": 1, //use to connect to project table
"project_coder": 1 // use to connect to employees table
}
Projects table
{
"id":1,
"name": "First Project"
}
To deal with this is best to create pivot table like employee_task
where table will have just two columns task_id and employee_id
then you can define in Task model
public function employees()
{
return $this->belongsToMany('\App\Employee', 'employee_task');
}
and Employee model
public function tasks()
{
return $this->belongsToMany('\App\Task', 'employee_task');
}
now you can see all employee tasks and rest of you relations work just fine
$data = Employees::find($id);
$data->tasks //you get all tasks assigned to this employee
$data->tasks()->first()->projects //you get all your projects for first task
$data->tasks()->first()->employees //all employees assigned to first task with this employee
Also recommend to you to lookup pivot tables, attach(), detach() and sync() functions. you can check it here : https://laravel.com/docs/5.7/eloquent-relationships#updating-many-to-many-relationships
UPDATE:
Ok I understand now what you are trying to do. You already have pivot table. I was little confused with your Project model which is not necessary.
You can remove your Project class if you have it just for this relation
and update your model relations as I wrote above. You don't need project_id and project_coder_id in this relation. Also change the column names to more conventional names like employee_id and task_id as I mentioned or whatever your table names are.
And you can rename employee_task pivot table name to your project table or you can rename it as well.
EDIT
When you use Project model for another data, you need to create 4th table as I mentioned above.
FINAL
drop project_coder column in Tasks table - unecessary column
create pivot table employees_task with employee_id,task_id
create mentioned relations with pivot table
I assume that Project hasMany() tasks and Task only belongsTo() one project. So need to create these relations as well.
Then you can use these relations like this:
$employee = Employee::find($id);
$task = Task::find($id);
$project = Project::find($id);
$employee->tasks //all tasks assigned to employee
$task->employees //all employees assigned to task
$task->project //project info assigned to task
$employee->tasks()->first()->project //project data from first task of employee
$project->tasks()->first()->employees //all employees assigned to first project task

PHP-Laravel get data from pivot table in manytomany relation

I facing problem in fetching specific data from pivot table (manytomany relation). The scenario is that I want to fetch data from pivot table between two specific dates. When I use this code
$user_availability = $user->dates->where('date','>=' , $start_date)->where('date','<=' , $end_date)->get();
foreach ($user_availability as $date)
{
echo $date->pivot->afternoon;
}
It gives me following error
Type error: Too few arguments to function Illuminate\Support\Collection::get(), 0 passed in C:\xampp\htdocs\codehacking\app\Http\Controllers\UsersController.php on line 210 and at least 1 expected
User Model:
public function dates()
{
return $this->belongsToMany('App\Date')->withPivot('morning', 'afternoon','night','comment');
}
Pivot table
I can provide more information if you need. Any help would be appreciated.Thanks!
From Laravel documentation.
Querying Relations
Since all types of Eloquent relationships are defined via methods, you
may call those methods to obtain an instance of the relationship
without actually executing the relationship queries.
Relationship Methods Vs. Dynamic Properties
If you do not need to add additional constraints to an Eloquent
relationship query, you may access the relationship as if it were a
property.
Change the query to
$user_availability = $user->dates()->where('date','>=' , $start_date)->where('date','<=' , $end_date)->get();
parenthesis are used in the relation dates to querying the relation.

Can I use php artisan db:seed to seed related tables?

Is it possible to seed related tables using the following in Laravel 5?
php artisan db:seed
I have two tables
users
id
first name
projects
id
name
and a pivot table
project_user
project_id
user_id
I would like to create a number of users, a number of projects and then relate the users and their respective projects.
Seeding the users and projects isn't a problem but I am not sure how to handle the pivot table.
Is it possible?
Of course you can. If you are using Eloquent, you can simply work with normal relations (maybe the easiest way). Or if you use the SQL builder directly, you can feed the table just as normal, but you need to stick to your foreign key rules.
Just give in a try and you'll see. But make sure you import classes you use.
Adding a relation between two models is easy, but there are some differences between the common relation types (and he perspective): one-to-many, many-to-one and many-to-many.
One-to-Many and Many-to-One
Assumed that each of your project has a creator, an owner so-to-say, you could have a 1:n relation between User and Project.
public class User {
public function ownedProjects() {
return $this->hasMany('App\Project');
}
}
public class Project {
public function owner() {
return $this->belongsTo('App\User');
}
}
In this relation, you can either attach a Project to a User or tell the Project who his owner is.
// Attach a project to an user
$project = Project::create([]);
User::find($id)->ownedProjects()->save($project);
// There is also a function saveMany() for an array of projects
// Tell the project who his owner is
$project = Project::create([]);
$project->owner()->associate(User::find($id));
Many-to-Many
In your case, we need a Many-to-Many relation between Users and Projects. The syntax is a bit different, but the outcome quite straight forward. First we need a relation between the both models:
public class User {
public function projects() {
return $this->belongsToMany('App\Project');
}
}
public class Project {
public function users() {
return $this->belongsToMany('App\User');
}
}
Then we can query the relation just like that:
$project = Project::create([]);
User::find($id)->projects()->attach($project->id);
You can also attach a whole bunch of projects, do the same things from the other side, detach models or synchronize them, if you want to make sure that an exact amount (and only this amount) is in relation:
// Adds a relation for the user to projects with ids 1, 2, 4 and 6
User::find($id)->projects()->attach([1, 2, 4, 6]);
// Adds the users with ids 19 and 173 to this project
Project::find($id)->users()->attach([19, 173]);
// Removes the user 19 from the projects relations
Project::find($id)->users()->detach(19);
// Removes all relations between this user and projects that are
// not listed in the synchronization array and adds a relation
// to all projects where none exists yet
User::find($id)->projects()->sync([4, 7, 19, 6, 38]);
This is the normal syntax for Many-to-Many relations, but you can also attach models just like in a One-to-Many relation:
// Creation of project could also be done before and saved to a variable
User::find($id)->projects()->save(Project::create([]));

Categories