at the moment i try to learning Laravel and Laravel Eloquent.
I try to solve a problem using relations in Laravel.
I have following Database Structure in my simple Laravel Project.
table players:
id name
table clubs:
id name icon
table players_x_clubs:
player_id club_id
it's a one to many Relation.
Is it possible to get the full club Object who is combined with the player_id?!
The first try was to add this to my Player Model
public function club()
{
return $this->hasOne('App\PlayersXClub');
}
Here, i only get the PlayersXClub Relation with the player_id and the club_id
but i want to get the full club object from the club table, is it possible in a simple way?
any ideas how i have to realize is it correctly?
my solution was this:
public function getClubRelation()
{
$clubRelation = $this->hasOne('App\PlayersXClub')->get()->first();
$club = Club::whereId($clubRelation->club_id)->get()->first();
return $club;
}
With this solution i can do this in my code $player->getClubRelation()->icon
but i don't know if its correct solved or is there a more simple way to resolve it with Eloquent?
You always have access to objects relations. For example:
$player = Player::find(1);
$club = $player->club;
or better
$player = Player::with('club')->find(1);
However, I believe you don't need an additional table. An additional table would result in a many to many relation which doesn't make much sense here.
A player belongs to a single club and a club can have many players. So it's one to many.
You should add a club_id foreign key to players table.
$table->unsignedBigInteger('club_id');
$table->foreign('club_id')->references('id')->on('clubs')->onDelete('cascade');
Player Class
public function club() {
return $this->belongsTo(Club::class);
}
Club Class
public function players() {
return $this->hasMany(Player::class);
}
I am trying to query data from my database and pass the results to a view called events, the problem I have is that one of my queries will always return the same result because in the where condition the $events_id is the same always. Is there a better way to do the querying? A better logic?
This code is from my controller called EventController:
public function index()
{
$firm_id = DB::table('firms')->where('user_id', auth()->id())->value('id');
$events_id = DB::table('events')->where('firm_id', $firm_id)->value('id');
$events = DB::table('events')->where('firm_id', $firm_id)->get()->toArray();
$actual_events = DB::table('actual_events')->where('event_id', $events_id)->get()->toArray();
return view('events',['events' => $events,'actual_events' => $actual_events]);
}
Since the $events_id is the same every time, the $actual_events will only contain the first result.
The image I have uploaded shows the problem, my table's first three columns are fine. Starting from the fourth they contain repeated values:
As I guess, you need something like this:
$event_ids = DB::table('events')->where('firm_id', $firm_id)->pluck('id');
$actual_events = DB::table('actual_events')->whereIn('event_id', $event_ids)->get()->toArray();
or write about your problem in details and I will try to help you.
you just said that your tables have relation together.
in this case it's better you using the eloquent for that,
first you should type the relations in model of each table like this:
class User extends Authenticatable{
public function cities()
{
return $this->hasmany('App\City'); //you should type your relation
}
}
for relations you can use this link: laravel relationships
after that when you compact the $user variable to your view, you can use this syntax for getting the city value relation to this user: $user->cities;.
I am storing information on a 4-day class. The information is dates 1-4 and each date has an instructor associated with it as there can be different instructors on different days. Let's just talk about day_1 and instructor_day_1 for now. My models are as follows:
Course Model:
public function instructor()
{
return $this->belongsTo('App\Instructor');
}
Instructor Model:
public function course()
{
return $this->hasMany('App\Course');
}
When i go to the #show method in my controller, i find the correct course but when i try to load the view, i can't figure out how to access the foreign relation. Right now i'm trying:
<p class="card-text">{{$course->day_1}} assigned to {{$course->instructor_day_1->instructor->name}}</p>
But that's not yielding anything but errors. If i do {{$course->instructor_day_1}}, i get the correct value from the database.
Is my relationship backwards? Does Course model need be "belongsToMany"? What is the correct syntax for pulling the instructor info? Do i need to specify any foreign key relations in my models?
belongsTo is the correct relationship, but it's not set up correctly. And you'll need 4 of them, 1 for each foreign key on the courses table.
This should get you started:
public function instructorDay1()
{
return $this->belongsTo('App\Instructor', 'instructor_day_1');
}
And then you would call it like this, to get instructor's name:
$course->instructorDay1->name;
And you'll need to do this for all 4 relationships.
I have 3 databases:
Routes:
id
name
Rates:
Id
Route_id
Car_id
Cars:
id
name
My model for routes
public function rates()
{
return $this->hasMany('App\Rate', 'route_id');
}
My model for rates
public function car() {
return $this->belongsTo('App\Car','car_id');
}
Now I need to access the car relation, but when I do
return $this->route->with('from','to','rates.car')->paginate(74);
I get null for the car relation
{"id":1,"from_id":1,"to_id":2,"distance":400,"created_at":null,"updated_at":null,"from":{"id":1,"name":"\u0410\u043a\u043a\u043e","created_at":null,"updated_at":null,"lat":32.93310000000000314912540488876402378082275390625,"long":35.0827000000000026602720026858150959014892578125},"to":{"id":2,"name":"\u0410\u0440\u0430\u0434","created_at":null,"updated_at":null,"lat":31.261399999999998300381776061840355396270751953125,"long":35.21490000000000009094947017729282379150390625},"rates":[{"id":1,"route_id":1,"car_id":1,"rate":1123,"night_rate":1391,"car":null},{"id":5551,"route_id":1,"car_id":2,"rate":1123,"night_rate":1391,"car":null},{"id":11101,"route_id":1,"car_id":3,"rate":1123,"night_rate":1391,"car":null},{"id":16651,"route_id":1,"car_id":4,"rate":1123,"night_rate":1391,"car":null},{"id":22201,"route_id":1,"car_id":5,"rate":1123,"night_rate":1391,"car":null},{"id":27751,"route_id":1,"car_id":6,"rate":1123,"night_rate":1391,"car":null},{"id":33301,"route_id":1,"car_id":7,"rate":1123,"night_rate":1391,"car":null},{"id":38851,"route_id":1,"car_id":8,"rate":1123,"night_rate":1391,"car":null}]},
From my understanding you are trying to access a Car model through a Route model.
A couple of things I noticed that should help you find a solution.
First off I think the inverse relation you are supposed to use the belongToMany() function instead.
public function car() {
return $this->belongsToMany('App\Car','Rates'); // Perhaps call the table something like routes_cars to more clearly define it's a pivot table
}
Next I see you are trying to use model functions within the context of $this(). I assume you are doing this in your model? That logic should be in a controller, that might cause some undesired results but I'm not entirely sure. Also it looks like your parameters are incorrect when using with(). You use the function name that you defined in belongsToMany()
App/Route::with('car')->paginate(74);
With the correct relationships setup you rarely need to worry about the pivot table. If you are going to add extra information in the pivot table there are laravel functions to help you do that in the documentation.
Let me explain what i try to achieve.
lets say i have 20 car types for example sport car or family car etc, and 5 cars for example porsche.
When i create a car i have the option to check multiple car types at the same time that belongs to the car and than save it.
I have done some homework and it looks like using a pivot table is the way to go for this inside laravel.
I have this method inside my cars model:
public function types()
{
return $this->belongsToMany('types', 'car_types');
}
And this method inside my types model:
public function cars()
{
return $this->belongsToMany('Car');
}
My tables looks like this:
cars
- id
- name
- created_at
- updated_at
types
- id
- name
- created_at
- updated_at
car_types
- car_id
- type_id
What im trying to do inside my controller is:
$car = new Car();
Car::create( Input::except('types') );
foreach(Input::get('types') as $type)
{
$car->types()->associate($type);
$car->save();
}
This is giving me the following error:
Call to undefined method Illuminate\Database\Query\Builder::associate()
I hope someone can help me out with this.
Thanks in advance.
Well you are almost there. You're right that the two models, Car and Type are in a many to many relation.
In your models you have code that says:
return $this->belongsToMany('types', 'car_types');
and
return $this->belongsToMany('Car');
Error #1:
In the types() method of the Car model as the first parameter you should pass the name of the model, and not the name of the table. So you should change that to something like:
return $this->belongsToMany('Type', 'car_types');
Error #2
In your Car model you're defining the pivot table as car_types, but the pivot definition is missing from the Type model. Either remove , 'car_types' from the types() method in Car model and rename your pivot table to simply car_type, or add , 'car_types' to your cars() method in Type model.
Error #3
Once all the model stuff is set up correctly, you could do in your controller this:
$car = new Car();
$car->name = Input::get('car_name_form_field_name_attribute');
$car->save();
$types = Input::get('types');
$car->types()->sync($types);
Error #4
I'm not sure if this is just a copy/paste error, but your pivot table seems to be missing a primary key field. Every table needs a primary key field, so your car_types table should look something like this:
car_types
id
car_id
type_id
You could also use attach() instead of sync(). More about the difference between these two here
Please try out this code and let us know if it works out.