I am new to Laravel and Eloquent and i am trying to create a football game plan.
For now i have 4 tables (with some example entries):
teams (all teams)
+---------+-----------+
| team_id | team_name |
+---------+-----------+
| 1 | Arsenal |
| 2 | Chelsea |
+---------+-----------+
competition (all competitions)
+----------------+------------------+
| competition_id | competition_name |
+----------------+------------------+
| 1 | Premier League |
+----------------+------------------+
schedule (schedule to the competitions)
+----+----------------+----------+--------------+--------------+-----------+-----------+
| id | competition_id | matchday | home_team_id | away_team_id | home_goal | away_goal |
+----+----------------+----------+--------------+--------------+-----------+-----------+
| 1 | 1 | 1 | 1 | 2 | 3 | 2 |
| 2 | 1 | 2 | 2 | 1 | 0 | 3 |
+----+----------------+----------+--------------+--------------+-----------+-----------+
schedule_teams (matches the schedule teamid with the teams id over the competition_id and the schedule_team_id)
+----+------------------+----------------+----------+
| id | schedule_team_id | competition_id | teams_id |
+----+------------------+----------------+----------+
| 1 | 1 | 1 | 1 |
| 2 | 2 | 1 | 2 |
+----+------------------+----------------+----------+
And here are my current classes:
Schedule.php
public function competition()
{
return $this->belongsTo(Competition::class, 'competition_id', 'competition_id');
}
Competition.php
public function schedule()
{
return $this->hasMany(Schedule::class, 'competition_id', 'competition_id');
}
With
$id = \request('competition_id');
$schedule = Schedule::where('competition_id', $id)->with('competition')->get();
i get the schedule with the home and away id's from schedule.
The question now is, how can i get the entries from the teams table over the schedule_teams table to a specifiy home and away id, also for example home_team_id = 1:
home_team_id (=1) -> schedule_team_id (=1) and competition_id (=1) -> teams (Arsenal)
I want the data from schedule and the associated teams in a collection to output in a blade.
can anyone help or give me improvement tips for a football database?
You should make use of the hasManyThrough relationship.
If you create say Schedule\Team, and then have that like the following.
public function schedule() {
$this->belongsTo(Schedule::class, 'schedule_id');
}
public function team() {
$this->belongsTo(Team::class, 'team_id');
}
Now in your Schedule class, you can have the following.
public function teams() {
$this->hasManyThrough(Team::class, Schedule\Team::class, 'schedule_id');
}
It should also be noted, that you don't need competition_id in your schedule team. Since a team belongs to a schedule, which belongs to competition, you can get it like that.
If you also want your Team to know about its schedules, you can add this to Team.
public function schedules() {
return $this->hasManyThrough(Schedule::class, Schedule\Team::class);
}
You Schedule\Team class becomes essentially, a glorified representation of a pivot table, but having it as a model, allows you to expand upon it in the future. It also helps keep everything neat.
Hope that makes sense.
Related
I have four tables
jobposts:
id | user_id | cat_id | job_title
1 | 1 | 1 | job 1
2 | 1 | 2 | job 2
3 | 2 | 3 | job 3
4 | 1 | 3 | job 4
categorymasters:
id | category_name
1 | cat1
2 | cat2
3 | cat3
4 | cat4
lastsubcategoryselectedbycompanies:
id | jobposts_id | lastsubcategorymasters_id
1 | 1 | 1
2 | 1 | 2
3 | 2 | 3
4 | 1 | 3
lastsubcategorymasters:
id | LastSubCategoryName
1 | lastsubcat1
2 | lastsubcat2
3 | lastsubcat3
4 | lastsubcat4
jobposts have unique rows.
lastsubcategoryselectedbycompanies is a mapping of jobposts and lastsubcategorymasters.
Now assume some user is logged in with their credentials (EX: take user_id 1 in jobposts). Now I need to show LastSubCategoryName in a comma separated list from the lastsubcategorymasters table, grouped by the jobposts, lastsubcategoryselectedbycompanies and lastsubcategorymasters tables.
allpostedjob.blade.php is:
#foreach($jobposteddetails as $jobposteddetail)
<tr>
<td>{{ $jobposteddetail->job_title }}</td>
</tr>
#endforeach
cotroller is:
public function index()
{
$user = Auth::user();
$jobposteddetails = jobpost::with('categorymaster')->where('user_id', '=', $user->id)->get();
return view('jobprovider.allpostedjob', compact('user','jobposteddetails'));
}
jobpost.php model is:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class jobpost extends Model
{
function categorymaster()
{
return $this->belongsTo(categorymaster::class, 'cat_id');
}
}
It is working proper.
But I also need to show LastSubCategoryName grouped by the tables jobposts, lastsubcategoryselectedbycompanies and lastsubcategorymasters.
function lastsubcategory()
{
return $this->belongsTo(lastsubcategoryselectedbycompanies::class);
}
It is not working. How can I fetch my result?
I am not very skilled at applying complex queries with eloquent, I prefer to use DB query builder with the join method
https://laravel.com/docs/5.8/queries
I have a sponsorship app I'm creating and trying to get a pivot table working between my users and kids, but when I have a user sponsor a kid, the pivot table kid_user is not populated with the kid_id or the user_id. Not sure what I'm missing.
A Kid can have as many users (sponsors) as their slots allow them.
Users can sponsor a kid, multiple kids or the same kid multiple times
if needed.
Here is my kid_user pivot table:
public function up()
{
Schema::create('kid_user', function (Blueprint $table) {
$table->integer('kid_id')->unsigned()->index();
$table->foreign('kid_id')->references('id')->on('kids')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->primary(['kid_id', 'user_id']);
});
}
Then on the User model: The user can have many kids...
public function kid()
{
return $this->hasMany(Kid::class);
}
Then on the Kid model: The kids can have many users...
public function user() {
//return $this->belongsTo(User::class); (Tried this..)
return $this->hasMany(User::class);
}
Here are the tables I'm using. (Only relevant info is included in the tables)
+---------------------+
| Tables_in_Database |
+---------------------+
| kid_user |
| kids |
| users |
+---------------------+
+-----------------------------+
| users table |
+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
| 1 | John | Smith |
| 2 | Jane | Doe |
+----+------------+-----------+
+-----------------------------+
| kids table |
+----+------------+-----------+-------+
| id | first_name | last_name | slots |
+----+------------+-----------+-------+
| 1 | Bobby | Little | 3 | -> Can be sponsored 3 times
+----+------------+-----------+-------+
+--------------------+
| kid_user table | THE BELOW RESULTS ARE WHAT I'M LOOKING FOR.
+--------------------+
| *kid_id | *user_id | * = Primary Key
+---------+----------+
| 1 | 1 | -> Sponsored 1st Slot
+---------+----------+
| 1 | 2 | -> Sponsored 2nd Slot
+---------+----------+
| 1 | 1 | -> Sponsored 3rd Slot
+---------+----------+
So when a User sponsors a Kid. I would like the kid_id & user_id to be entered into the kid_user pivot table. Any help would be appreciated.
First of all you might wanna rename the functions in your models in plural as it does not have one but many from the relationship.
So in your user model add this:
public function kids()
{
return $this->belongsToMany(Kid::class);
}
And in your Kid model:
public function users()
{
return $this->belongsToMany(User::class);
}
Then in order to save to the pivot table since your table naming is correct, just doing:
$user->kids()->attach($kid);
Will save it properly in the pivot table. Making sure first that you have existing User and Kid for the variables. More details here
I am looking forward to implement a website dealing with teachers, students and parents. In the database I made, I've created a user table and 3 children tables : teachers, students, parents.
See below the table structure
User table
+--------+----------+----------+-------+
| id (PK)| username | password | email |
+--------+----------+----------+-------+
| 1 | user1 | 123 | ... |
+--------+----------+----------+-------+
| 2 | user2 | 132 | ... |
+--------+----------+----------+-------+
| 3 | user3 | 321 | ... |
+--------+----------+----------+-------+
Student table
+---------------+--------------+
| users_id (PK) | class |
+---------------+--------------+
| 1 | highschool |
+---------------+--------------+
| 3 | middleschool |
+---------------+--------------+
Teacher table
+--------------+-------------------+---------------------+
| users_id (PK)| subscription_type | end_of_subscription |
+--------------+-------------------+---------------------+
| 2 | monthly | 2017-10-25 |
+--------------+-------------------+---------------------+
And the parents table also have a PK which corresponds to a user id.
I just started to learn laravel and I really wonder how could I handle this properly maybe with eloquent with Laravel 5.4.
I am giving you some hints I think you can do rest and as your question is not specific I am guessing you are thinking how can you relate/join tables, so
Create three model let say User, Student, Teacher.
In Student & Teacher model create a method like below
public function user()
{
return $this->hasOne(User::class, 'id', 'users_id');
}
Now you can query like :
$student = Student::find($id) ;
$name = $student->user->name;
$email = $student->user->email ;
Or
$teachers = Teacher::where('subscription_type', 'monthly')->with(['user'])->get();
dd($teachers);
I think you need to update your database structure, you need pk & fk
column separated.
I have three tables like these:
// users
+----+-----------+
| id | user_name |
+----+-----------+
| 1 | Jack |
| 2 | Peter |
| 3 | John |
+----+-----------+
// skills
+----+------------+
| id | skill_name |
+----+------------+
| 1 | PHP |
| 2 | HTML |
| 3 | Laravel |
| 4 | MySQL |
| 5 | jQuery |
+----+------------+
// skill_user
+----------+---------+
| skill_id | user_id |
+----------+---------+
| 2 | 1 |
| 5 | 1 |
| 1 | 2 |
| 2 | 2 |
| 4 | 2 |
+----------+---------+
Now I want to get all skills of one specific user. I can do that by using a join clause in a raw sql query:
SELECT s.skill_name
FROM skills s
JOIN skill_user su ON s.id = su.skill_id
WHERE su.user_id = :user_id
/* output (assuming :user_id is 1)
+------------+
| HTML |
| jQuery |
+------------+
Ok All fine. Now I want to know, how can I do that by adding a method in the model of Laravel framework? All I'm trying to do is using belongsTo(), hasOne(), hasMany() etc ..
To do in Eloquent way, you need to add the relationship. In your case, it is many-to-many relationship so in User.php, add this function to declare the relationship:
public function skills() {
$this->belongsToMany(\App\Skill::class, 'skill_user', 'user_id', 'skill_id');
}
Then,
Access it like this to eager load it:
$users = \App\User::with('skills')->get();
OR
Say you have a single user,
$user = User::where('id', 1)->first(); // Get the user with id = 1
and to get the skill for that user:
$user->skills;
OR
If you don't want to do using Eloquent way, you can use Query Builder. Note that, using this method, you basically join it manually so you don;t need to add any method to the Model:
\DB::table('users')
->join('skill_user', 'skill_user.user_id','=', 'users.id')
->join('skills', 'skill_user.skill_id', '=', 'skills.id')
->select('*')
->where('users.id', 1)
->get();
You have to use belongsToMany relationships. Assuming you will create SkillUser model for skill_user table. Add the following code to User Model
public function skills() {
$this->belongsToMany('App\SkillUser', 'skill_user', 'user_id', 'skill_id');
}
Now you can access it by
$users->skills();
I assume you are talking about Many to Many relationship between Users and skills, then the example given in Laravel many-to-many speaks about it.
I'm using Laravel 5 and Eloquent, I have 3 tables setup:
photos
+----+---------------+------------------+
| id | photo_name | photo_location |
+----+---------------+------------------+
| 1 | kittens.jpg | C:\kittens.jpg |
| 2 | puppies.jpg | C:\puppies.jpg |
| 3 | airplanes.jpg | C:\airplanes.jpg |
| 4 | trains.jpg | C:\trains.jpg |
+----+---------------+------------------+
photo_set (pivot table)
+------------+----------+
| set_id | photo_id |
+------------+----------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
+------------+----------+
sets
+----+----------------+
| id | description |
+----+----------------+
| 1 | cute animals |
| 2 | transportation |
+----+----------------+
I created a belongsToMany relationship in my photos and sets models to link these two together.
class Photo extends Model {
public function sets()
{
return $this->belongsToMany('App\Set');
}
}
and
class Set extends Model {
public function photos()
{
return $this->belongsToMany('App\Photo');
}
}
However I'm trying to reference the $Sets->photos() model function in my controller, so that given a set of id=1, I can return the photo_location value for each row [C:\kittens.jpg,C:\puppies.jpg], but I don't know how to access it..
Also, I can "sort of" access this information in the view with:
#foreach($sets as $set)
{{$set->images}}
#endforeach
but it looks like it only iterates through once and returns a json (?) of the necessary information, though I'm not sure how to parse that to regular HTML either.
So in short, I'm having trouble accessing this data (photo_location) from both the controller and the view
Use Collection::lists()
$locations = Set::find(1)->photos->lists('photo_location');
It will return an array ['C:\kittens.jpg', 'C:\puppies.jpg']
http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_lists
In your controller try this :
$result = PhotoSet::where('set_id', $set_id)
->with('sets')
->with('photos')
->get();
$photo_location = $result->photos->photo_location;
here PhotoSet is the model for photo_set table, because it is a pivot table we will be able to access both sets and photos table from it.