How to make relationship between three table in laravel eloquent - php

I have three tables, Sections,Questions and options.
Each Section has many questions and each question has many options.
How can I fetch data from this tables related to each other?
Section model relationship with Question model
class Section extends Model
{
use HasFactory;
protected $primaryKey='sectionid';
public function questions(){
return $this->hasMany(Question::class,'sectionid')->orderBy('order');
}
}
Question model relationship with Option model:
class Question extends Model
{
use HasFactory;
protected $primaryKey='questionid';
public $timestamps = true;
public function options(){
return $this->hasMany(Option::class,'questionid');
}
}
my query:
$data=Section::with('questions')
->where('formid',$formId)
->orderBy('sectionid')
->get()
->toJson();
It returns this:
I want each questions member contains options array related to it.

You can use nested relation in with like below.So it will fetch question options also
$data=Section::with(['questions','questions.options'])
->where('formid',$formId)
->orderBy('sectionid')
->get()
->toJson();

Related

join three table relation by laravel eloquent model

I have three table which is explained below
User
id
email
password
specialities
id
name
active
results
id
specialitie_id
user_id
result
color
i am trying to relate results with the rest of the 2 tables, but i don't know how to do it, below is my model relation, please correct me if there's any issue, i can't fetch the data due to having wrong relation
Result Model
class Result extends Model
{
use HasFactory;
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function speciality()
{
return $this->belongsTo(Speciality::class);
}
}
User Model
class User extends Authenticatable implements MustVerifyEmail
{
public function result()
{
return $this->hasMany(Result::class);
}
}
i am trying to expect a correct result of my relation database tables in laravel
Since the results table is Intermediate Table Columns.use laravel belongsToMany method so no need to create results model.Treat results table as pivot table.
In User Model add relation like below
public function specialities()
{
return $this->belongsToMany(Speciality::class,'results')->withPivot('result','color');
}
Also read here Many To Many Relationships

Laravel 5 – get particular many to many relation based on model and related model ID

I've got Tag and Attendee Eloquent models, they are in many-to-many relation. Pivot table has also two more attributes – value_int and value_string. My Attendee model looks like this:
class Attendee extends Model
{
public $timestamps = false;
protected $fillable = [
'event_id'
];
public function tags() {
return $this->belongsToMany('App\Models\Tag', 'attendee_tag', 'attendee_id', 'tag_id')
->withPivot(['value_string', 'value_int']);
}
public function scoreTagValue($tag_id) {
return $this->tags->where('tag_id', '=', $tag_id)->first();
}
}
What I want is to obtain pivot values based on Attendee model and variable tag_id, so I've written scoreTagValue function, but it always returns null and I don't know why :( I'm calling it this way:
$attendee->scoreTagValue($tag_id). Thanks for your help :)
You need to access the relation, not the property:
public function scoreTagValue($tag_id) {
return $this->tags()->where('tag_id', '=', $tag_id)->first();
}
Also, according to the docs, withPivot() does not take an array, so:
->withPivot('value_string', 'value_int');

how to convert joins query to laravel eloquent query

I have query bulider's query like this
$schedule = DB::table('users')
->join('tblHomeCourts','users.homeCourtId','tblHomeCourts.homeCourtId')
->join('tblUserHomeCourts','tblUserHomeCourts.userId','users.userId')
->join('tblSchedules','tblUserHomeCourts.userHomeCourtId','tblSchedules.userHomeCourtId')
->select('tblHomeCourts.homeCourtName', 'tblHomeCourts.address','tblSchedules.timeFrom','tblSchedules.timeTo','tblSchedules.duration','tblSchedules.scheduleStatus','users.firstName','users.lastName','users.profilePic','users.userId')
->where(['tblSchedules.scheduleStatus'=> 0,
])->where('timeFrom','>',$request->currentTime)
->where('timeTo','>',$request->currentTime)
->where('tblUserHomeCourts.homeCourtId',$homeCourtId)
->get();
Now, I want to convert this into proper eloquent query using eloquent relationship I'm fully messed up with relationships can somebody please help me to find out the solution?
thanks :)
To achieve this we have to define relationships among the related table for the first place. Then we need to load the joint table using the with method.
For example you User model should look like this:
class User extends Model{
protected $table = 'users';
public function homeCourt(){
//Many to one relation between user and homeCourt
return $this->belongsTo(HomeCourt::class, 'homeCourtId', 'homeCourtId');
}
public function userHomeCourts(){
//One to many relation between user nad userHomeCourt
return $this->hasMany(UserHomeCourts::class, 'userId', 'userId');
}
}
Your HomeCourt model should look like:
public class HomeCourt extends Model{
protected $table = 'tblHomeCourts';
public function user(){
//One to many relation between homeCourt and user
return $this->hasMany(User::class, 'homeCourtId', 'homeCourtId');
}
}
Your UserHomeCourt model should look like:
public class UserHomeCourt extends Model{
protected $table = 'tblUserHomeCourts'
public function user(){
//Many to one relation between userHomeCourts and users
return $this->belongsTo(User::class, 'userId', 'userId');
}
public function schedules(){
//One to many relation between userHomeCourts and schedule
return $this->hasMany(Schedule::class, 'userHomeCourtId', 'userHomeCourtId');
}
}
Your Schedule model should look like:
public function Schedule extends Model{
protected $table = 'tblSchedules';
public function userHomeCourt(){
//Many to one relation between schedule and userHomeCourts
return $this->belongsTo(UserHomeCourt::class, 'userHomeCourtId', 'userHomeCourtId');
}
}
Now you are ready to build your query. This query is bit different than the query you have built using query builder. Besides, the output of laravel eloquent query is also different. You have to adjust that result with you view:
You can query like this:
$users = User::with('homeCourt', 'userHomeCourts.schedule')->where('timeTo', '>', ,$request->currentTime)->get();
This query is just an example, you have to define it according to your requirement. Here, the parameters of with methods are the methods name of that users table relation with other tables. This is how it works.
You can read more here: https://laravel.com/docs/5.4/eloquent-relationships

Laravel withtrashed in a relationship

I have an Order model and a Service model.
An order can be deleted (soft delete).
I want to list all orders, deleted and active and the service that it belongs to.
Order Model:
class Order extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function service ()
{
return $this->belongsTo('Service');
}
}
Service Model:
class Service extends Model
{
public function order()
{
return $this->belongsToMany('Order');
}
}
What I tried:
$company=Company::with('orders.service'=>function ($query) {
$query->withTrashed();
},'services'])->where('id',$company->id)->get();
But this returns no orders (and right now I only have 1 deleted order in my db)
Any ideas?
Thanks!!
you can use
public function order() {
return $this->belongsToMany('Order')->withTrashed();
}
First of all, a belongsToMany relationship always goes with another belongsToMany relationship at the other side, so you are not doing right the relationships.
If you want a many to many relationship, both models should have a belongsToMany relationship to the other model, and you must have a pivot table.
If you want a one to many relationship, one model should have a belongsTo relationship and the other a hasMany relationship.

Laravel - eager loading a method (not a relationship) of an Eloquent model

Like we can eager load a relationship of an Eloquent model, is there any way to eager load a method which is not a relationship method of the Eloquent model?
For example, I have an Eloquent model GradeReport and it has the following method:
public function totalScore()
{
return $scores = DB::table('grade_report_scores')->where('grade_report_id', $this->id)->sum('score');
}
Now I am getting a collection of GradeReport Eloquent models.
$gradeReports = GradeReport::where('student_id', $studentId)->get();
How can I eager load the returning values of totalScore method for all GradeReport Eloquent models in the collection?
You can add arbitrary properties to your models by adding them to $appends array and providing a getter. In your case the following should do the trick:
class GradeReport extends Model {
protected $appends = ['totalScore'];
public function getTotalScoreAttribute() {
return $scores = DB::table('grade_report_scores')->where('grade_report_id', $this->id)->sum('score');
}
}
Now all GradeReport objects returned from your controllers will have totalScore attribute set.
The table grade_report_scores would also have an eloquent model xyz on which you define a relationship, query scopes, functions, etc.
Add relationship into GradeReport model:
public function scores()
{
return $this->hasMany('xyz', 'grade_report_id', 'id');
}
Now you can rewrite your totalScore function into this:
public function totalScores()
{
return $this->with(['scores' => function ($query) {
$query->sum('score');
}])->get();
}
not tested, note the closure, there bight be a need to call $query->select('id', 'srore', 'other used values');

Categories