please help.I have a test booking table that looks like this
Schema::create('test_bookings', function (Blueprint $table) {
$table->unsignedInteger('RequestID');
$table->string('bookingDate');
$table->string('timeSlot');
$table->unsignedInteger('nurse_id');
$table->timestamps();
});
and a tests table that looks like this
Schema::create('tests', function (Blueprint $table) {
$table->unsignedInteger('RequestID');
$table->unsignedInteger('patientID');
$table->string('barcode');
$table->string('temperature');
$table->string('pressure');
$table->string('oxygen');
$table->unsignedInteger('nurseID');
$table->timestamps();
});
I want to show the RequestID,bookingDate,timeSlot, name and surname of the nurse only if the test_bookings RequestID is in tests table. This is my nurse table
Schema::create('nurses', function (Blueprint $table) {
$table->unsignedInteger('nurseID');
$table->string('name');
$table->string('surname');
$table->string('idNumber');
$table->string('phone');
$table->string('email');
$table->unsignedInteger('suburb_id');
$table->timestamps();
$table->index('suburb_id');
});
This is the code that i tried
$tests = DB::table('tests')
->select('RequestID','bookingDate','timeSlot','name','surname')
->join('nurses','nurses.nurseID','test_bookings.nurse_id')
->join('test_bookings','test_bookings.RequestID','=','tests.RequestID')
->get();
but when I join the tests table nothing is showing
that because you are using join clause that generate innerJoin statement, and to see the results you should use leftJoin
$tests = DB::table('tests')
->select('RequestID','bookingDate','timeSlot','name','surname')
->leftJoin('nurses','nurses.nurseID','=','test_bookings.nurse_id')
->leftJoin('test_bookings','test_bookings.RequestID','=','tests.RequestID')
->get();
Why you're not using ORM here, a simple one-to-one relationship can do the job perfectly. Here is an example:
class TestBooking extends Model {
# Other code...
public function nurse(){
return $this->belongsTo(Nurse::class);
}
}
class Test extends Model {
# Other code...
public function testBooking(){
return $this->belongsTo(TestBooking::class, 'RequestID','RequestID');
}
}
Now you can get all data like this:
$tests = Test::with("testBooking","testBooking.nurse")->get();
// and get data inside loop like this:
$test->RequestID // to get request ID
$test->testBooking->bookingDate // to get booking date
$test->testBooking->timeSlot // to get timeSlot
$test->testBooking->nurse->name // to get nurse name
$test->testBooking->nurse->surname // to get nurse surename
To know more about relationships read documention.
Related
I've got a problem i can't get through, here are my models:
Cloth.php
public function selling(): BelongsTo
{
return $this->belongsTo(Selling::class);
}
Selling.php
public function clothes(): HasMany
{
return $this->hasMany(Cloth::class);
}
And now it's anything ok and pretty basic... but then came this model:
Accessory.php
public function selling(): BelongsTo
{
return $this->belongsTo(Selling::class);
}
And now it's the problem: I need (i think) a polymorphic relationship but i can't understand how to make it in this specific case.
I have 2 starting models to morph to 1 model but every example i found have 1 starting model to morph to 2 models.
Do i need a polymorphic relationship?
I can't really get out of this.
Thanks!
You are basically looking for a one to many polymorphic relationship. Here is how to do it:
Let's say your tables are structured like bellow;
Schema::create('sellings', function (Blueprint $table) {
$table->id();
$table->integer('relation_id');
$table->string('relation_type');
$table->timestamps();
});
Schema::create('accessories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('details');
$table->timestamps();
});
Schema::create('cloths', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description');
$table->timestamps();
});
Selling.php
public function relation(){
return $this->morphTo();
}
Cloth.php
public function selling(){
return $this->morphOne(Selling::class, 'relation');
}
Accessories.php
public function selling(){
return $this->morphOne(Selling::class, 'relation');
}
Then, you can query using bellow approach;
$selling = Selling::findOrFail(1)->relation;
Now when you dd($selling) you get exactly what you are looking for from a correspondent table;
Please remember that the relation_type field needs to exactly correspond the model. See bellow screenshot for example;
What happens here is when you create a polymorphic function called test the database fields need to follow with test_type corresponding to model and test_id corresponding to the id of the model/database table.
I have a comments table which in turn can contain replies to comments via the parent_id table.
Attached, is the migration
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->string('comment');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('commentable_id');
$table->string('commentable_type');
$table->unsignedBigInteger('parent_id')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('parent_id')->references('id')->on('comments')->onDelete('cascade');
$table->timestamps();
});
Attached, Model Relationship
public function replys()
{
return $this->hasMany(Comment::class, 'parent_id');
}
I would like to bring all comments and their replies sorted by id desc.
This way I get the parents back correctly but I need to sort the replys as well.
$comments = $this->post->comments()->with('user', 'replys')->get();
$comments = $comments->sortByDesc('id')->values()->all();
How should I do it? thank you very much
I think it's possible to do it in 2 ways:
1 - You can add an orderBy method directly to the relation
public function replys()
{
return $this->hasMany(Comment::class, 'parent_id')->orderBy('created_at');
}
2 - You can chain the orderBy Method on a controller or wherever you're using the relation.
class Controller
{
public function index()
{
$replies = Model::find(1)->replys()->orderBy('created_at')->get();
}
}
Please, try this solution and check if it works for you!
I have created two table to store post information:
Posts table where I store overall information except categories.
Migration file of each table looks like this:
posts
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->string('slug');
$table->longText('excerpt');
$table->longText('description');
$table->tinyInteger('feature')->default(1);
$table->enum('status',['publish','draft']);
$table->string('image');
$table->timestamps();
});
post_categories
Schema::create('post_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('category_id')->nullable();
$table->unsignedBigInteger('post_id')->nullable();
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('post_id')->references('id')->on('posts');
$table->timestamps();
});
Now, I have following function in PostCategory model:
public function post(){
return $this->belongsToMany(Post::class);
}
Now, when I try to fetch data using following:
\App\Models\PostCategory::find(5)->post()->orderBy('created_at')->get();
I get call to member function post() on null
What should I do to get post with the category 5?
You misunderstood some concepts.
Here your relationship is between post and categories.
In post Model
public function categories(){
return $this->belongsToMany(Category::class,'post_categories','post_id','category_id');
}
In the Category model
public function posts(){
return $this->belongsToMany(Post::class,'post_categories','category_id','post_id');
}
Now, You're free to access posts from category and categories from post.
$post = Post::with('categories')->where('id',5)->first();
By this, you'll get a post with its categories.
$category= Category::with('posts')->where('id',5)->first();
By this, you'll get category with its posts.
Check more detail how many to many work
Edit:-
If by using post you want to make a condition in the categories then.
$post = Post::with('categories')->whereHas('categories', function($q){
$q->where('id',5);
})->get();
Hey guys In a new project for a client I have to make a filtration system for books that have genres.
I've made a many to many relationship and a pivot table. So far I've made the form with check boxes, because the goal is to query a combination of two or more genres and show only the results that have all the selected genres.
My migrations are:
Schema::create('genres', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 40);
$table->timestamps();
});
Schema::create('books', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 125);
$table->timestamps();
});
Schema::create('book_genre', function (Blueprint $table) {
$table->increments('id');
$table->integer('genre_id')->unsigned();
$table->foreign('genre_id')->references('id')->on('genres')->onDelete('cascade');
$table->integer('book_id')->unsigned();
$table->foreign('book_id')->references('id')->on('books')->onDelete('cascade');
$table->timestamps();
});
My model is:
class Book extends Model{
public function genres(){
return $this->belongsToMany('App\Genre', 'book_genre');
}
}
This is my controller where I take the Get array with genre IDs:
class FilterController extends Controller
{
public function index()
{
$genreIds = Input::get('genres');
$books = Book::whereHas('genres', function($q) use ($genreIds){$q->whereIn('genres.id', $genreIds);})->orderBy('created_at', 'desc')->paginate(10);
}
return view('filter.index', compact('books'));
}
Here the problem is that it is not filtering the results by a combination of the genres, it is filtering them simply if they have one of the genres.
What should I change so I can query out only the matching books what have the listed genres?
$query = Book::with('genres');
foreach($genreIds as $genreId){
$query->whereHas('genres', function($q) use ($genreId){
$q->where('id', $genreId);
});
}
$filteredBook = $query->get();
I found the same solution in Stackoverflow
Having some problems retrieving nested relationship data. Here are my models:
class Partner extends Model
{
public function admins()
{
return $this->hasMany(Resource::class)->where('resource_type', 'Admin');
}
}
class Resource extends Model
{
public function details() {
return $this->belongsTo(ResourceDetail::class);
}
}
class ResourceDetail extends Model
{
}
When I try $this->partner->admins[0]->details it's giving null. The sql it generated is: "select * from resource_details where resource_details.id is null". I'm not quite sure why is it null in the query. I must have done something wrong with the relations. I tried $this->partner->with('admins.details')->find($this->partner->id)->toArray();. It's getting the admins, but details is still null. I also tried hasManyThrough, like: return $this->hasManyThrough(ResourceDetail::class, Resource::class)->where('resource_type', 'Admin'); it finds "unknown column". This is my database structure:
Schema::create('partners', function (Blueprint $table) {
$table->increments('id');
});
Schema::create('resources', function (Blueprint $table) {
$table->increments('id');
$table->integer('partner_id')->nullable()->unsigned();
$table->foreign('partner_id')->references('id')->on('partners')
->onUpdate('cascade')->onDelete('set null');
$table->enum('resource_type', constants('RESOURCE_TYPES'))->nullable();
$table->integer('resource_detail_id')->unsigned();
$table->foreign('resource_detail_id')->references('id')->on('resource_details')
->onUpdate('cascade')->onDelete('cascade');
});
Schema::create('resource_details', function (Blueprint $table) {
$table->increments('id');
});
Do I need to change the structure? Or, how can I get the data from current structure? All I want is, a partner has many resources, and a resource has one details.
From that error I think you may be trying to call $this->partner->admins[0]->details from a model that doesn't have an id. What is $this in context to?