Laravel 5 has one relationship - laravel-5

I have two tables: drugs table and formulations table. The drugs table has fields id, name, quantity and formulation_id. The formulations table has fields id and name.
What relationship should I use to get the drugs records including the name of the formulation.
Note that 1 drug record has only one 1 formulation record.
I have tried using hasOne relashionship but doesn't work:
My view looks as follows:
#foreach($drugs as $drug)
<li>
<a class="padded-list" href="">{{$drug->name}} ({{$drug->formulation->name}})</a>
</li>
#endforeach
My model relationship in the the Drug model looks as follows:
public function formulation()
{
return $this->hasOne('App\Formulation');
}

Your formulation() method in your Drug model should be:
public function formulation()
{
return $this->belongsTo('App\Formulation');
}

If you call $drug->formulation return Eloquent Collection, you can't get name
You should call $drug->formulation()->first()->name

Good day, formulation() in Drug model shoud be
public function formulation()
{
return $this->belongsTo('App\Formulation');
}
If one formulation can have many drugs, Drugs() in Formulation model shoud be
public function drugs()
{
return $this->HasMany('App\Drug');
}
You can get formulation by this way
$drug->formulation()->first()->name
or
$drug?->formulation?->name
in new php versions

Related

Invalid argument supplied for foreach() in laravel when use Eloquent: Relationships

I wanna get the class name of a user via the user ID. When I input the ID of a user so I will wanna get the class name. I have three tables such as users table, classes table, and class_users table. The class_users table is born from two users table and classes table.
A users table has an id, name, email, password.
A classes table has an id, class_code, class_name.
A class_users table has an id, class_id, user_id
And this problem relates to Eloquent Relationships.
Thank you for help.
My Route:
Route::get('/find_classes/{id}','StudentController#find_classes');
My Controller function:
public function find_classes($id)
{
$users = User::find($id);
foreach($users->classes as $class)
{
echo $class->name . '<br';
dd($class);
}
}
My User Model:
public function classes()
{
return $this->belongsTo('App\Classes','class_users','user_id','class_id');
}
Looks like you might have the wrong relationship set up on your User model. You have a one to many set up, but your DB is setup to handle a many to many. I suggest you change your User model relationship:
public function classes()
{
return $this->belongsToMany('App\Classes');
}
Note, you may need to name the FK on that relation, as I see you have class_id on the table, but your actual class is named 'Classes'. Check through your relationships to ensure this is explicit on the FK where it doesn't follow Laravel convention exactly.
With this relationship, your foreach loop should work. It would be a good idea for efficiency, as mare96 noted, to eager load the classes on the $users collection when you query:
$users = User::with('classes')->find($id);

Laravel pivot with multiple columns

Hi I have a problem with Laravel`s pivot table.
I have the following tables: students, courses and lessons.
The table lessons is connected with courses through a foreign key courses_id, and the tables students and courses are connected through a pivot courses_students.
So I can access the information through students like this:
//Students model
public function courses()
{
return $this->belongsToMany(Courses::class,'courses_students','student_id', 'course_id')
->with('lessons');
}
//Courses model
public function lessons()
{
return $this->hasMany(Lesson::class);
}
This works completely fine for this kind of relationship, but I want to add a third column in the pivot with name lesson_id for the lessons table.
I am doing this because, sometimes I need to get a specific set of lessons from each course for each user.
I succeeded in doing so, by using a model courseStudent for the pivot table.
Using the model for pivot my calls became like this.
Student->with('courseStudent.courses')
->with('courseStudent.lessons')
->get();
This partially does what I need it to do, but I want to maintain the relation ship between courses and students.
Is there a way to achieve that?
Example from docs(go through Many To Many):
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
Pivot table is meant to use belongsToMany relationship on both entities.
So your students and courses should have it defined if you want pivot table between that is using eloquent default capacity.
As a side note pay attention on naming convention because that way you will reduce issues on minimum: pivot table should be tableanamesingular_tablebnamesingular where order is set by alphabetical order of tables' names (i.e. post_user Yes, user_post No).
Id fields in pivot table should be tablenamesingular_id.
You can set names however you want but this way you will have less unepected behavior in future using eloquent. All of this you have in documentation page and I recommend you go through it thoroughly.
Other way is to use dynamic properties for getting certain values. Example from docs:
$user = App\User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->created_at;
}
If you would like to manually change values in pivot table, you should create separate model for it that would be connected with that entity/table (pay attention that pivot model extends Pivot as in example from docs rather than Model):
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class PostUser extends Pivot
{
// other definitions related
}
You can use join for third relation:
public function courses(){
return $this->belongsToMany(Courses::class,'courses_students','student_id', 'course_id')
->withPivot('lesson_id')
->join('lessons','lesson_id','=','lessons.id')
->select('lessons.id','lessons.title', ...);
}
If you are going to use the same pivot table for courses and lessons, you can to do something like this:
//Students model
public function courses()
{
return $this->belongsToMany(Courses::class,'courses_students','student_id', 'course_id')
->whereNotNull('course_id');
}
public function lessons()
{
return $this->belongsToMany(Lessons::class,'courses_students','student_id', 'lesson_id')
->whereNotNull('lesson_id');
}
Then just use it:
$courses = $student->courses;
$lessons = $student->lessons;

Laravel - Filter records by distinct relation

Right now I have the following models structure,
Country -> State -> City -> Student
And the Student model includes first_name and last_name.
So, I want countries to by filtered by giving student's first name. Like if I give John then I want list of countries which has students whose first name is John.
I was trying something like this,
I added a method called Students() in Country model and returning Student instances from that method. But now I stuck to find out how to filter countries.
Thanks in anticipation.
I came across a similar question recently and I came with the following solution myself. Probably, there are easier ways, but this will get you going for now, I guess.
First we query all the users with first_name == John, as you described, and we limit the query to output only the ID's.
$users = User::where('first_name', 'John')->get()->pluck('id');
We then cross-compare this with the result of Students() from the country model. As I don't know what you're querying for to get the country that you want, I'll just take the Netherlands as an example — that's where I'm from.
$users = Country::where('name', 'the Netherlands')->students()->whereIn('id', $users)->get();
For this to work, you must make sure that within the Students()-function in your model, the get() is left out.
Final 'result':
$users = User::where('first_name', 'John')->get()->pluck('id');
$users = Country::where('name', 'the Netherlands')->students()->whereIn('id', $users)->get();
in the Student Model create this:
public function city()
{
return $this->belongsTo(City::class,'city_id', 'id');
}
and in the City Model create this:
public function state()
{
return $this->belongsTo(State::class,'state_id', 'id');
}
Finally in the State Model:
public function country()
{
return $this->belongsTo(Country::class,'country_id', 'id');
}
For example if you made things like that in controller:
$students = Student::where('name', 'John')->get();
in the view:
#foreach($students as $student)
$student->city->state->country->country_name;
#endforeach
You can access like that.
If you have setup the model and relationship properly then you need to call them using in with function
$students = Student::where('name','John')->with('city.state.country')->get();
Loop through the $students
#foreach($students as $student)
{{ $student->city->state->country }}
#endif

How my model Laravel could be return me all prices for each item only last date in hasMany?

I have 2 models(market,price_item), i want return last prices for each item (model 2) for 1 market (model 1).
i have in my model 1:
public function prices()
{
return $this->hasMany(MarketPrices::class, self::IDMarket)->groupBy(['item']);
}
This solution give me price for each item but not last price.
I tried orderBydesc but not work.
Thanks you for your help
First of all this is not how you create a relation
A "one-to-many" relationship is used to define relationships where a single model owns any amount of other models. For example, a blog post may have an infinite number of comments. Like all other Eloquent relationships, one-to-many relationships are defined by placing a function on your Eloquent model:
public function prices()
{
return $this->hasMany('Models/MarketPrices', 'id');
}
call it like
$price = Yourmodel::find(1);
dd($price->prices); //return the 1 model connected

Laravel: check relationship

Please bear with me, i'm bad at explaining things and i don't think the title suits my problem.
I have a User model and a Course model.
These models have a manytomany relationship.
There currently are 4 Courses, but the User only has a relationship with 2 of them (lets say Course 1 and 3).
On a certain page i'd like to output all Courses, and highlight the Courses the User has a relationship with, so it can view the Course. So, Course 1 and 3 will be highlighted, while Course 2 and 4 will be faded.
User model:
public function courses()
{
return $this->belongsToMany('App\Course');
}
Course Model:
public function users()
{
return $this->belongsToMany('App\User');
}
The Controller
public function index()
{
$member = $this->auth->user();
$courses = $this->courserepository->getAllCourses(); // Course 1,2,3,4
$member_courses = $member->courses; // Course 1,3
// Logic to filter courses which are in a relationship with the User
return view('member.course.index', compact('member', 'courses'));
}
I wish i had some more code, but i have deleted most of it since it was not working as suspected.. I'm looking for someone to point me in the right direction.
In controller replace:
$member = $this->auth->user()->with('courses');
then in view:
<ul>
#foreach($courses as $course)
<li#if(in_array($course['id'], array_column($member['courses'], 'id'))){{' class="highlighted"'}}#endif>
{{$course->name}}
</li>
#endforeach
</ul>

Resources