Laravel orm Order by custom attribute - laravel-4

In my user model I have added custom attribute get number of post user have created.
I can successfully get that but when I have try to order by it give error.
1054 Unknown column 'posts' in 'order clause'

Can you let us know what is the Eloquent query you're running? Also make sure that the name of the table you're using is correct.
EDIT:
Does the posts column exist in the users table? Or are you trying to get all the posts from the Post Model and order the posts by their name in descending order?
If that is what you want to do then you would need to go to your User Model and set up your relationship with posts.
In User Model create this method:
public function posts() {
return $this->hasMany('Post'); // Post would be the name of the Posts Model
}
In Post model do this:
public function user() {
return $this->belongsTo('User'); // Where User is the name of the Users Model
}
Then according to the Laravel documentation you could do someonething like this with the query:
$users = User::with(array('posts' => function($query)
{
$query->orderBy('name', 'desc'); // assuming that 'name' would be the column in the posts table you want to sort by
}))->take(5)->get();
I hope I am correct and this helps and that solves your issue.

Related

Laravel eloquent for four tables

I'm new to Laravel. I am developing a project. and in this project I have 4 tables related to each other
-Users
-Orders
-OrderParcels
-Situations
When listing the parcels of an order, I want to get the information of that order only once, the user information of that order once again, and list the parcels as a table under it. so far everything ok. but I also want to display the status of the parcels listed in the table as names. I couldn't add the 4th table to the query. do you have a suggestion? I'm putting pictures that explain the structure below.
My current working code is
$orderParcels = Orders::whereId($id)
->with('parcels')
->with('users:id,name')
->first();
and my 'orders' model has method
public function parcels(){
return $this->hasMany(OrderParcels::class);
}
public function users(){
return $this->hasOne(User::class,'id','affixer_id');
}
Note[edit]: I already know how to connect like this
$orderParcels = DB::table('order_parcels as op')
->leftjoin('orders as o','op.orders_id','o.id')
->leftjoin('users as u','o.affixer_id','u.id')
->leftjoin('situations as s','op.status','s.id')
->select('op.*','o.*','u.name','s.situations_name')
->where('op.orders_id',$id)->get();
but this is not working for me, for each parcels record it returns me orders and user info. I want once orders info and once user info.
Laravel provides an elegant way to manage relations between models. In your situation, the first step is to create all relations described in your schema :
1. Model Order
class User extends Model {
public function parcels()
{
return $this->hasMany(OrderParcels::class);
}
public function users()
{
return $this->hasOne(User::class,'id','affixer_id');
}
}
2. Model Parcel
class Parcel extends Model {
public function situations()
{
return $this->hasOne(Situation::class, ...);
}
}
Then, you can retrieve all desired informations simply like this :
// Retrieve all users of an order
$users = $order->users; // You get a Collection of User instances
// Retrieve all parcels of an order
$parcels = $order->parcels; // You get a Collection of User instances
// Retrieve the situation for a parcel
$situations = $parcel->situations // You get Situation instance
How it works ?
When you add a relation on your model, you can retrieve the result of this relation by using the property with the same name of the method. Laravel will automatically provide you those properties ! (e.g: parcels() method in your Order Model will generate $order->parcels property.
To finish, in this situation where you have nested relations (as describe in your schema), you should use with() method of your model to eager load all the nested relation of order model like this :
$orders = Orders::with(['users', 'parcels', 'parcels.situations'])->find($id)
I encourage you to read those stubs of Laravel documentation :
Define model relations
Eager loading
Laravel Collection
Good luck !
Use join to make a perfect relations between tables.
$output = Orders::join('users', 'users.id', '=', 'orders.user_id')
->join('order_parcels', 'order_parcels.id', '=', 'orders.parcel_id')
->join('situations', 'situation.id', '=', 'order_parcels.situation_id')
->select([
'orders.id AS order_id',
'users.id AS user_id',
'order.parcels.id AS parcel_id',
'and so on'
])
->where('some row', '=', 'some row or variable')->get();

Laravel Intermediate relations data error

Here is my RecentViewController file code:
$contents = RecentView::where('user_id', $loggedUser)
->with('posts')
->with('profile')
->paginate(12)->toArray();
and my RecentView model code is as follows:
public function posts()
{
return $this->hasOne('App\FeedPost', 'id', 'post_id');
}
public function profile()
{
return $this->belongsTo('App\Profile', 'user_id', 'id');
}
the data i receive after running this code shows logged in users details instead of posts users detaisl. how can i change retreiving posts users data instead of logged users data?
I guess you are trying to get the user of the post
In order to get posts users detail you need to move profile relation into Post model. I hope there's a user_id in posts table. then get profile relationship of post model with dot notation as follows
$contents = RecentView::where('user_id', $loggedUser)
->with('posts.profile')
->paginate(12)->toArray();

Retrieving eloquent models with constraints on both the parent and child/associated model

I'm trying to retrieve all Eloquent Models that match a particular field in the Parent Model ('Event') and the child model ('Dates').
I've hit an issue whereby Laravel is stating that my field ('date') doesn't exist in the child class, but I can't understand why. Can someone please point me in the right direction and explain where I've gone wrong?
Essentially, what I'm trying to achieve is the retrieval of all Events with the approved tag being true AND where the event date is of a particular day, in this case the 10th.
I've done some searching around and looked at some of the examples in the Laravel documentation. I've set up the ('Event') model to have a one to many relationship with the ('dates') model. I can see that I can chain queries together, but things get a little confusing when dealing with more than one model at a time (in the same query)
This is my attempt at retrieving the data.
public function calender()
{
$events = Event::where('approved', true)->with('EventDates')->whereDay('date', '10')->get();
return view('events.calender');
}
This is a snippet from my ('Event') Model. I've only included the most relevant information here as there are many attributes .
class Event extends Model
{
//
public function user(){
return $this->belongsTo(User::class);
}
public function dates()
{
return $this->hasMany('App\EventDate');
}
}
This is a snippet from my ('EventDate') model migration file showing that 'date' is indeed a field of the ('EventDate') model. Once again, I've just included the most relevant function here.
class CreateEventDatesTable extends Migration
{
public function up()
{
Schema::create('event_dates', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
$table->date('date')->nullable();
$table->time('startTime')->nullable();
$table->time('endTime')->nullable();
$table->unsignedBigInteger('event_id');
$table->index('event_id');
});
}
}
I'd like to be able to retrieve a list of the matching Events that have the approved attribute set to true, and the Event Dates on a particular day (xxxx-xx-10)
Right now, I'm getting the error that the date column can't be found:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'date' in 'where clause' (SQL: select * from events where day(date) = 10 and approved = 1)
I think this is what you are looking for:
$events = Event::where('approved', true)
->with(['dates' => function ($query) {
return $query->whereDay('date', '10');
}])
->get();
Note: I assume your relation between an Event and it's EventDate is called dates
In this way you are applying filtering by day on the related data (EventDate) and not on the Event model.
you should mention the table name for the date column.
->whereDay('event_dates.date', '10')
I managed to find a way around using the eloquent commands by using the DB Query builder instead and it now works (taking into account Shankar's point above)
I altered the code to this (It's a little more specific than what I wrote before, but it should be able to guide others to solving their issue):
for($day = 5; $day <12; $day++)
{
$events = DB::table('events')
->join('event_dates', 'events.id', '=', 'event_dates.event_id')
->select('events.*', 'event_dates.startTime as startTime', 'event_dates.endTime AS endTime')->where('events.approved', '=', true)->whereDay('event_dates.date', '=', $day)
->orderBy('event_dates.startTime', 'asc')->get();
array_push($events_list, $events);
}
```
I can't understand why the Eloquent queries couldn't find the table, but this seems to work, so for those stuck, this may be less "eloquent" but at least it works ;-;

Eloquent hasManyThrough also get middle table information

I have same table structure as mentioned in laravel document for HasManyThrough relationship hasManyThrough
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
and define a relationship like same as in doc.
public function posts()
{
return $this->hasManyThrough(
'App\Post', 'App\User',
'country_id', 'user_id', 'id'
);
}
Now when I List posts of specific country. I need the information of user of the post too. I mean information from pivot table(users)
$posts = Country::find(2)->posts();
The above returns post data only..
What you need is to eager load the users alongside the posts, can be achieved via the with() method on the Builder:
$posts = Country::find(2)->posts()->with('user')->get();
If you're loading huge amounts of data and don't want the whole User instance loaded, you can even specify which fields to only be retrieved from the users table:
$posts = Country::find(2)->posts()->with('user:id,name')->get();
Then you can simply use $post->user->name or whatever you need when iterating your collection.
Refer to the documentation for more information.
Try this one:
$posts = Country::find(2)->posts()->with('user')->get();

Laravel 5 eloquent: select specific column of relation

I have 2 models: Author and Post
In my Post model, I have an author function (One To Many (Inverse)):
public function author()
{
return $this->belongsTo('App\Author', 'author_id');
}
Now I want to export to Excel the following information:
id | title | author name
This is what I tried:
$posts = Post::with(array(
'author' => function ($query) {
$query->select('name');
}))->select('id', 'title')->get();
What I get is an empty author's name column.
What do I wrong?
Since Laravel 5.5 you can use eager loading retrieve multiple specific columns simply by using string
Post::with('author:id,name')->get()
Author::with('posts:id,author_id,title')->get()
Notice the id or foreign key (author_id) must included, or data will be null.
please try:
$posts = Post::with(['author' => function($query){
$query->select(['id','name']);
}])->get(['id','title', 'author_foreign_key_in_posts_table']);
Having that, you'll be able to get:
$posts->first()->author->name;
$posts->first()->id;
$posts->first()->title;
You may use iteration or whatever instead of first() for export.

Resources