OrderBy With relationships - laravel

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!

Related

Do i need a One-to-Many polymorphic relationship?

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.

Selecting from multiple tables in laravel

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.

How to get parent_id count?

Users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name');
$table->string('last_name');
$table->string('referral_code')->nullable();
$table->integer('parent_id')->unsigned()->nullable();
$table->string('mobile')->unique();
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Order table
public function up()
{
Schema::create('oreders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->bigInteger('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->timestamps();
});
}
I tried first and whereHas('user') replaced it
$orderCount = Order::whereHas('user')->withCount('parent_id')->get();
return $orderCount;
I get this error.
Call to undefined method App\Order::parent_id() (View: C:\xampp\htdocs\site\bazar\resources\views\Admin\master.blade.php)
You first need to define the relationship in your models App\User and App\Order
App/User.php
class User extends Model
{
public function orders()
{
return $this->hasMany(Order::class);
}
public function parent()
{
return $this->belongsTo(User::class, 'parent_id');
}
public function children()
{
return $this->hasMany(User::class, 'parent_id');
}
}
App/Order.php
class Order extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
I do believe you want to count the number of order for a user.
But first of all, we will fix some issues / I'm suspecting you have.
Table name orders is called oreders
You don't need to verify if an order has a user Order::whereHas('user') since $table->bigInteger('user_id')->unsigned(); is not nullable. It means an order cannot exists without a user.
Not an issue but a suggestion $table->bigInteger('user_id')->unsigned(); can be simplified with $table->unsignedBigInteger('user_id');
Now the interesting part
$orderCount = Order::whereHas('user')->withCount('parent_id')->get();
return $orderCount;
In my understand you're trying to get the number of orders of of a parent of the user. I will show you some use case that may help your understanding.
// Get the total number of orders
$orderCount = Order::count();
// Get the total number of orders of a user
$userOrderCount = $user->orders()->count();
// Include the number of orders in the user attributes
$user = User::withCount('orders')->find($userId); // notice 'order' is, in fact `orders()` from the App\User methods
// Include the number of orders in the parent attributes
$parent = User::withCount('orders')->find($user->parent_id);
// Number of orders of the parent
$parentOrderCount = Order::where('user_id', $user->parent_id)->count();
// Edit: As you commented, you also want to know "The marketers can see how many people bought their code"
// I'm assuming this is the number of children (I have added the relation in the model above)
$childrenCount = $user->children()->count()
Note : when you do Order::where('user_id', $user->parent_id)->count(); you don't need to verify that the user has a parent first. parent_id will return null and user_id cannot be null. So it will just return 0

Get all categories of post in Laravel

I create a table post__post_category_relations to save categories of post.
Schema::create('post__post_category_relations', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('post_id')->unsinged();
$table->integer('category_id')->unsinged();
$table->timestamps();
});
At blade template edit post, I want show list categories of post.
In Post model I wrote:
public function categories(){
return $this->belongsTo(PostCategoryRelations::class,'id','post_id','category_id');
}
But it only return one category. Can you show me how to show all categories? Thank so much!
This looks similar to Many To Many approach between posts and categories. And a junction table which connects post and category table should have post_id, category_id and other columns are not required like id , timestamps() i guess you won't be using them in your application.
Migration would minimize to
Schema::create('post__post_category_relations', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->integer('post_id')->unsinged();
$table->integer('category_id')->unsinged();
});
For many to many you can add definitions in your models like
class Post extends Model
{
public function categories()
{
return $this->belongsToMany(Category::class, 'post__post_category_relations', 'post_id');
}
}
class Category extends Model
{
public function posts()
{
return $this->belongsToMany(Post::class, 'post__post_category_relations', 'category_id');
}
}
If you still want to keep other columns from junction table post__post_category_relations you can access them by defining as pivot attributes in your model like
class Post extends Model
{
public function categories()
{
return $this->belongsToMany(Category::class, 'post__post_category_relations', 'post_id')
->withPivot('id','cols')
->as('post__post_category_relation_cols');
}
}

How to retrieve Nested Relationship data in laravel 5 using eloquent?

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?

Resources