Laravel - ordering posts by date and get them with pagination - laravel

I was wondering how can I take posts from the database ordered from the latest to the oldest but with pagination.
This is my current code:
return view('index', [
'featured' => Post::orderBy('created_at', 'desc')->first(),
'posts' => Post::orderBy('created_at', 'desc')->skip(1)->take(6)->get(),
]);
So, I am taking the latest post as "featured" and for the rest of the posts I want to skip first (because it is already taken as "featured" one) and take others from the latest to the oldest but with pagination.
EDIT
If someone need this later this piece of code worked for me
$featured = Post::orderBy('created_at', 'desc')->first();
$posts = Post::orderBy('created_at', 'desc')->where('id', '!=', $featured->id)->paginate(2);
return view('index', [
'featured' => $featured,
'posts' => $posts,
]);

Try the below code:
return view('index', [
'featured' => Post::orderBy('created_at', 'desc')->first(),
'posts' => Post::orderBy('created_at', 'desc')->where(id, '!=', 1)->paginate(6),
]);

To display them and order them only by created_at
this code below worked for me:
$posts = Post::orderBy('created_at', 'desc')->get();

Related

Update two tables using one function in Laravel

I'm building an app using Laravel 5.7 and Vue.js2. I have two tables: departments and users. A user can be a chief of a department. I made the relationship between the models. I want it so that when I create a new department, the type of the chief will be changed on the user's table to 'chief.'
DepartmentController
public function store(Request $request)
{
$this->validate($request, [
'name' => 'string|required|max:191',
'bio' => 'string|required',
'user_id' => 'integer|required|unique:departements'
]);
return Department::create([
'name' => $request['name'],
'user_id' => $request['user_id'],
'bio' => $request['bio']
]);
}
Can you try this.
Controller
public function store(Request $request)
{
$this->validate($request,[
'name'=>'string|required|max:191',
'bio'=>'string|required',
'user_id'=>'integer|required|unique:departements'
]);
$new_department = Department::create([
'name'=>$request['name'],
'user_id'=>$request['user_id'],
'bio'=>$request['bio']
]);
$get_user = User::where('id', $request['user_id'])->first();
if($get_user)
{
$get_user->type = 'chief';
$get_user->save();
}
return ['message' => 'success'];
}
In this code, After saving the New Department I get the UserData in UserModel where id is the $request['user_id] then check it if exists.
If exists, I change the type to 'chief' and save.
If you have relationship between two models then you can update like this
$product = Department::with('relationship_function_name')->find($id);
$product->fields= $request->input_name;
$product->relationship_function_name->field_name = $request->input_name;
$product->update();
Hope this helps :)

Returning laravel realtionship within json

I am currently doing this as title says like this:
$user = User::where('username', request('username'))->first();
$posts = [];
$comments = [];
foreach($user->posts as $post){
foreach($post->comments as $comment){
array_push($comments, [
'id' => $comment->id,
'body' => $comment->body,
'user' => $comment->user->only(['name', 'id']),
]);
}
array_push($posts, [
'title' => $post->title,
'id' => $post->id,
'body' => $post->body,
'comments' => $comments,
]);
}
return response()->json([
'user' => $user->only(['name', 'avatar', 'age']),
'posts' => $posts,
]);
Is there a shorter way of doing this like:
$user->only(['name', 'avatar', 'age'])->withPostsOnly(['id', 'title', 'body'])->withCommentsOnly(['id', 'body']);
I know there is a way to make methods inside models that return these parts of data and then to use it same as above but shorter.
But is there any way to use something like getNameAttribute($value) for relations so I can say:
$user->only(['id', 'name', 'age', 'posts']);
And in posts value I need to have all posts and relationship data like comments and users that are connected to comments.
So basically in User model:
public function posts() {
return $this->hasMany('App/Post')->only('id', 'title', 'body', 'comments');
}
And inside Post model:
public function comments() {
return $this->hasMany('App/Comment')->only('id', 'body', 'user');
}
And inside Comment model:
public function comments() {
return $this->belongsTo('App/User')->only('id', 'name');
}
Thanks
You are probably overcomplicating it to be honest.
$user = User::where('username', request('username'))->first();
$user->load(['posts.comments']);
return response()->json($user);
This is a simplified version maybe but still should indicate you can just load relationships on models.

Returning Laravel many-to-many relations with clause options

There is code in Laravel:
$product = Product::where('slug', $slug)->with('types')->with('brand')->firstOrFail();
return $product;
I'm retrieving array with types array and brand array.
Types has boolean options "is_active"
How I can return $product with types that is_active
ex.
$product = Product::where('slug', $slug)->with('types')->with('brand')->where('types.is_active', '=', '1')->firstOrFail();
Try this out,
$product = Product::where('slug', $slug)->with([
'types' => function($query){ $query->where('is_active',true); } ,
'brand'
])
->firstOrFail();
Source docs, https://laravel.com/docs/5.6/eloquent-relationships#constraining-eager-loads
If you need only products which type is active, you can also filter them:
$product = Product::with([
'types' => function($query) { $query->where('is_active',true); },
'brand'
])
->where('slug', $slug)
->whereHas('types' => function($query) { $query->where('is_active',true); },
->firstOrFail();

How to update multiple rows of a table in Laravel?

Helper,
I wanna update multiple addresses for a particular user_id, with out changing its existing order. Also I'm using relation here.
public function update(Request $request, $id){
$data['id'] = $id;
$user = User::with('addresses')->find($id);
$j = $user['addresses'][0]['id'];
foreach($request->address_id as $key => $i){
$i++;
}
foreach($request->address1 as $key => $v){
if($j<$i){
$user->addresses()->whereUserId($data['id'])->update([
'address1' => $v,
'address2' => $request->address2[$key],
'state' => $request->state[$key],
'country' => $request->country[$key]
]);
}
$j++;}
}
I'm getting input somewhat like this,
{"_method":"PATCH","address_id":["92","93"],"address1":["aaa","xxx"],"address2":["bbb","yyy"],"state":["ccc","zzz"],"country":["India","India"]}
When I do my update the last input, which means, xxx,yyy,zzz,India is getting update for both rows92,93

Eager loading not working - Laravel

I have eager loaded the data but when I am using $object->attribute it again fetch the data from database.
My query is :
$user = User::with([
'Comment' => function($query){
$query->where('active', 1);
$query->with('CommentReply.User');
$query->orderBy('updated_at', 'desc');
}
]);
But when I use $user->comment then it again load all the comments, which results to N+1 problem. Any reason why this is happening? Thanks in advance.
Everything is working fine, just stick to one convention:
$user = User::with([
'comment' => function($query){
$query->where('active', 1);
$query->with('CommentReply.User');
$query->orderBy('updated_at', 'desc');
}
]);
//then
$user->comment
or
$user = User::with([
'Comment' => function($query){
$query->where('active', 1);
$query->with('CommentReply.User');
$query->orderBy('updated_at', 'desc');
}
]);
//then
$user->Comment
Notice letter casing.
Also mind that $comment->commentReply->user will do just the same, so you need to call $comment->CommentReply->User.

Resources