dd function not able to fetch content from database - php

I am building a post system in which user can post on his wall.Posts are created successfully and are saving into database but it can't be fetched from the database.
I've also relationship between user and posts.
my postcontroller:
public function getmyplace()
{
$posts=Post::where(function($query){
return $query->where('user_id',Auth::user()->id)
->orWhere('user_id',Auth::user()->friends()->lists('id')
);
})
->orderBy('created_at','desc')->get();
dd($posts);
$accounts=Account::orderBy('updated_at','desc')->limit(1)->get();
return view('myplace',['posts'=>$posts,'accounts'=>$accounts]);
}
public function postCreatePost(Request $request)
{
Auth::user()->posts()->create([
'body' => $request->input('body'),
]);
return redirect()->route('myplace');
}
my database:
output:

"Return" statement is not applyed in nested query builder and Collection::lists() method return array. Try this:
$posts = Post::where(function($query){
$query->where('user_id',Auth::user()->id)
->orWhereIn('user_id',Auth::user()->friends()->lists('id'));
})
->orderBy('created_at','desc')->get();
dd($posts);

Related

I am trying to pass searched query based on user input to my dompdf view

i want to use the result of that query and pass it into my pdfview and create a pdf based on the result. i have using sessions but did not work, is there any other solution
my controller for the search query:
public function index(Request $request){
$rsearch= $request->rsearch;
$fromdate= $request->fromdate ;
$todate= $request->todate ;
$rents = DB::table('rentcollection')
->join('tenants','rentcollection.AccountNo','=','tenants.AccountNo')
->join('propertys','tenants.PropertyID','=','propertys.PropertyID')
->select(DB::raw("CONCAT(tenants.OtherNames,' ',tenants.Surname) as
Fullname"),'rentcollection.Date as Date','rentcollection.Amount as
Amount','rentcollection.Period as Period','rentcollection.ReceiptNo as
Receipt','tenants.RegDate
as RegDate', 'tenants.AccountNo as Accno','tenants.Rent as Rent',
'tenants.NoOfProperty as
NoOfProperty','propertys.Address as Address','propertys.Property as Property')
->where('propertys.Address','like','%'.$rsearch.'%')
->whereBetween('Date', [$fromdate, $todate])
->paginate(20);
return view('reports.rent', compact('rents',));
}
my controller for creating pdf:
public function createPDF(Request $request){
$datas = $request->session()->get('cart');
$pdf = PDF::loadView('pdf.rent', ['orderedrent' => $datas,])->setPaper('A4','landscape');
return $pdf->stream('invoice.pdf');
}

Laravel get data after insert/update

I have this part of code:
$seller = Seller::where('tel', '=', $request->tel)->where('confirmed', '=', 1)->first();
if($seller){
$seller = Seller::where('tel', $request->tel)->update($input); //update
return response()->json(['message'=>'Seller Updated successfully!', 'data'=> $seller], 200);
} else {
$seller = Seller::create($input); //create
return response()->json(['message'=>'Seller created successfully!', 'data'=> $seller], 200);
}
Now want to return inserted or updated data in response, but after google and see lot of posts, all tried are failed, how can I do this? without last inserted id
but return boolean:
{
"message": "Seller updated successfully!",
"data": 1
}
How to get last insert id in Eloquent ORM laravel
Most topics want to return id but I want all data.
The key to your problem is understanding 3 Eloquent methods.
create() - Returns the inserted model instance.
update() - Returns a boolean (0 or 1) based on the success of the update statement.
refresh() - Refreshes a model instance by requerying the database.
As in the full example below, you need to treat create() and update() differently since they return different things.
For the create() you can leave it as-is. But the update() needs to be modified to not reassign the $seller variable.
That will stop any errors, but it will return the old data. In order to return the new data, you need to refresh the model (refresh()).
$seller = Seller::where('tel', '=', $request->tel)->where('confirmed', '=', 1)->first();
if ($seller){
// DO NOT reassign since update() returns boolean
Seller::where('tel', $request->tel)->update($input); //update
$seller->refresh(); // Refresh it here
return response()->json(['message'=>'Seller Updated successfully!', 'data'=> $seller], 200);
} else {
// This one is good since create() returns newly created model.
$seller = Seller::create($input); //create
return response()->json(['message'=>'Seller created successfully!', 'data'=> $seller], 200);
}
This is because you are overwriting your var $sellers with the response of the update method. And update() returns a boolean. Therefore, you don't have to assign the return value to the $seller var in the place of the update.
To return the updated seller model, use the fresh() method in your response. $seller->fresh().
$seller = Seller::where('tel', '=', $request->tel)->where('confirmed', '=', 1)->first();
if ($seller){
Seller::where('tel', $request->tel)->update($input); //update
return response()->json([
'message' => 'Seller Updated successfully!',
'data'=> $seller->fresh()
], 200);
} else {
$seller = Seller::create($input); //create
return response()->json(['message' => 'Seller created successfully!', 'data'=> $seller], 200);
}
In my case
$user = tap(User::where('id', $id))->update(['name' => $name]);. Now, you can return user: return $user->first();

Querying MorphToMany Relation Laravel

The thing I want to get from the database is that get all the posts with the data which will identify whether the post is liked by the auth()->user() or not. Most probably via count.
App\Post
public function likes()
{
return $this->morphToMany('App\User', 'likeable');
}
App\User
public function likePosts()
{
return $this->morphedByMany('App\Post', 'likeable')->withTimestamps();
}
Likeables Table
Likeables table has ('user_id', 'likeable_id', 'likeable_type')
I tried using orWhereHas
$posts = Post::with( ['user', 'tags', 'category'])->orwhereHas('likes', function($q) {
$q->where('user_id', auth()->id());
})->latest()->withoutTrashed()->paginate(10);
But with about query I am only getting those posts which the user has liked. I want to get all posts and a check whether the post is liked by the user or not
I came across whereHasMorph but it was only for morphTo and not for morphToMany.
#m____ilk I was able to solve this but creating a mutator:
public function isLiked()
{
return $this->likes()->where('user_id', auth()->id())->count() > 0;
}
I ran a loop on the posts and attached a custom attribute to a single post based on the mutator.
$posts = Post::with( ['user', 'tags', 'category', 'post.user', 'post.tags', 'post.category'])->latest()->withoutTrashed()->paginate(10);
foreach ($posts as $post) {
// Mutator Condition
if ($post->is_liked) {
// Custom Attribute
$post->isLiked = 1;
} else {
$post->isLiked = 0;
}
}
return $posts;
In laravel 9 I did something like:
$posts = Post::with( ['user', 'tags', 'category', 'post.user', 'post.tags', 'post.category'])
->withCount([
'likes',
'likes as is_liked' => function($q) {
$q->where('user_id', auth()->id());
}
])->latest()->withoutTrashed()->paginate(10)

Eloquent query returns wrong data when when using union

I have in my code a union between public data and user specific data. What I want to achieve is that if there is no user logged in, I return data which public is true. In case that I have a user, I make another query where user_id is the logged in user. Everything works until I want to get a specific data id of a user that I shouldn't be allowed.
For example I have the data:
[
'id' => 1,
'user_id' => 1,
'public' => true,
],
[
'id' => 2,
'user_id' => 1,
'public' => false,
],
My current code:
public function getQuery() : Builder
{
$publicData = $this->model->where('public', true);
// $this->user is passed thought another method which is $request->user() result.
if (!isset($this->user)) {
return $publicData;
}
if ($this->user->isAdmin()) {
return $this->model->newQuery();
}
return $this->model
->where('user_id', $this->user->id)
->union($publicData);
}
Now we assume that $this->user->id is 10 and I try to fetch data that I am not allowed by id.
$data = $this->getQuery()
->where('id', 2)
->first();
In this situation, always the first public data, which in this case is id 1 will be returned and I expect to receive null.
I am not sure how to find a solution for this and I am not sure what am I missing. Currently I use Laravel 6
Potential problem in your code, it is using one query for union and result query.
You can try check this:
public function getQuery() : Builder
{
// HERE ADDED newQuery
$publicData = $this->model->newQuery()->where('public', true);
// $this->user is passed thought another method which is $request->user() result.
if (!isset($this->user)) {
return $publicData;
}
if ($this->user->isAdmin()) {
return $this->model->newQuery();
}
return $this->model
->where('user_id', $this->user->id)
->union($publicData);
}
But you recommend simplify your query, without using union, because union is unnecessary here, to example:
public function getQuery() : Builder
{
$query = $this->model->newQuery();
if ($this->user->isAdmin()) {
return $query;
}
return $query->where(function ($builder) {
$builder->where('public', true);
if (isset($this->user)) {
$builder->orWhere('user_id', $this->user->id);
}
});
}
In Laravel you get the logged in user id by auth()->id(). It seems you are trying to filter the results by the eloquents’ attached users, which will obviously return true for every row.

reduce database query to one and avoid Call to a member function load() on null error

I have this function:
public function show($id)
{
if (count($post = Post::find($id))) {
$post = $post->load(['comments' => function ($q) {
$q->latest();
$q->with(['author' => function ($q) {
$q->select('id', 'username');
}]);
}, 'user' => function ($q) {
$q->select('id', 'username');
}]);
$this->authorize('seePost', $post);
return view('post.show', ['post' => $post]);
} else {
dd('no post');
}
}
I added the if statement as if I try to open a route to a non existent post id I get the error Call to a member function load() on null.
However now I have two queries, one looks for the Post in the DB and if it finds one then I have to load the relations with the second one. What can I do to go back to just one query with all the relations loaded and avoid the error? Any clue?
You can use Constraining Eager Loads do it like this:
https://laravel.com/docs/5.8/eloquent-relationships#constraining-eager-loads
$post = Post::with(["comments" => function ($query) {
// Order by created_at, query comment author & select id, username
$query->latest()->with(["author" => function ($q) {
$q->select("id", "username");
}]);
}, "user" => function ($query) {
// Query post author & select id,username
$query->select("id", "username");
}])
// Fetch post or throw a 404 if post is missing
->findOrFail($id);
// You can also return an empty post instance like this if post is missing
// ->findOrNew([]);
// Or return the post or null if post is missing
// ->find($id);
// Authorize
$this->authorize('seePost', $post);
return view("post.show", ["post" => $post]);
Laravel has an Eager Loading feature that would be helpfull in your case. Eager Loading allows you to autoload relations along with the same query that you use to retrieve your main model info. https://laravel.com/docs/5.8/eloquent-relationships#eager-loading
You could a below codes.
Easiest way is :
$post = Post::with('comments.author', 'user')
->find($id);
Or fine tune query with callback :
$post = Post::with(['comments' => function ($q) {
// if you use comments select, then you need to specify foreign key too
$q->select('id', 'author_id', 'details') // comment fields
->latest(); // Use chaining method
// OR use $q = $q->latest();
},
'comments.author' => function ($q) {
$q->select('id', 'username'); // author fields
},
'user' => function ($) {
$q->select('id', 'username'); // user fields
}])
->find($id);
In some cases you might need some modifications, bu in overall that should avoid you N+1 queries problem.

Categories