I'm new to laravel and I'm still trying to learn.
This my code in my controller:
public function index(User $user){
$posts = $user->posts()->with(['user', 'likes']);
return view('users.posts.index', [
'user' => $user,
'posts' => $posts,
]);
}
And this is the code on blade.php
{{$user->name}}
I've also tried checking if the code:
dd($posts = $user->posts()->with(['user', 'likes']));
and it seems fine since it's returning data from the database. With these codes it was supposed to show the User's Post on a different page when you click on the User's name. The problem is that it only shows the user's name but not the user's post. I'm only following a tutorial but the result was different with the tutorial and the one that I'm doing. Can someone please help?
I suppose you are trying to lazy eager load the posts relationship on this $user and load the user and likes relationship for those posts. You can try to use load to load these relationships on the Collection:
$posts = $user->posts->load('user', 'likes');
Or load on the User instance:
$user->load('posts.user', 'posts.likes');
$posts = $user->posts;
If you are not trying to have these relationships loaded on the $user but you just want the posts with their relationships you can eager load them off of the relationship itself:
$posts = $user->posts()->with('user', 'likes')->get();
Related
I am new to Laravel so please be patient with me.
i have to implement search functionality in Laravel. i am able to send form data to the search controller and receiving it as well
public function search_results(Request $request){
if ($request->has('gender')) {
echo $request->gender;
}
.....
}
Now when i am following tutorials on the web i am getting such examples :
public function filter(Request $request, User $user)
{
// Search for a user based on their name.
if ($request->has('name')) {
$user->where('name', $request->input('name'))->get();
}
}
or
public function index()
{
$users = User::where('status', 1)
->where('is_banned', 0)
->get(['name']);
dd($users);
}
now i am not sure from where this User:: or User $user is being added, and what should i do in my scenario.
Your suggestions would be helpful ..
Thanks
The $user represents an object belonging to the model(User::) associated with a table(users) in the mvc structure. If you want to "Search for a user based on their name." That means you already have a users table in database , and a User model .
You can use eloquent queries to retrieve data from database.
A User.php file should be generated when you create a new laravel project with composer. You can check for that.
So when you declare a variable like this :
$user = User::first();
You are actually getting the first element in 'users' table by using your User model.
If you can configure your User model and users table correctly , you should be able to get all records from your users table like this :
$users = User::all();
Then you can filter it like :
$users = $users->where('gender','male') // where('gender',$request->gender) in your situation
If you dont have a users table or a model , you can look to the document about how to create models using artisan commands Laravel API Doc. Generating Model Classes
Having Laravel 8 routing and controller issue
I'm bit new to laravel8 and got hang of it and I'm building a news portal as a project and learn at same time.
On the main index page I like to display some data such posts and categories and so on, where the data comes different tables in the db and from same controllers but different methods to the same route.
So I’m bit stuck here, the problem I’m having is that it’s not working
This is my code
Here are the routs
// main Index Page
Route::get('/','App\Http\Controllers\Home_pageController#categories);
// Index Latest Posts
Route::get('/','App\Http\Controllers\Home_pageController#homePageLatestPosts');
Methods in the Controllers
This is the method for displaying the latest posts in a sidebar
// Display latest limit by 10 the posts on home page
public function homePageLatestPosts(){
// $all_posts = Blogs::all();
$latest_posts = DB::table('blogs')->join('users', 'users.id', '=', 'blogs.added_by')->select('users.*','blogs.*')->orderBy('blogs.created_at', 'desc')->paginate(5);
// dd($latest_posts);
return view('welcome' , ['latest_posts'=>$latest_posts]);
}
// Show Categories
public function categories(){
$categories = DB::table('categories')->orderBy('category_name', 'desc')->get();
// dd($categories);
return view('welcome',['cats'=>$categories]);
}
I would like to know what the problem is and if there is a solution and if its the right approach that I', taking
I have googled around for a solution but not being able to solve it
thanks in advance
thanks for the responses.
i got a way around by fetching the data from DB in one method and passed them to the view for display.
use App\Models\Blog;
use App\Models\User;
use App\Models\Categories;
public function welcome(){
// Latest Posts
$latest_posts = DB::table('blogs')->join('users', 'users.id', '=', 'blogs.added_by')->select('users.*','blogs.*')->orderBy('blogs.created_at', 'desc')->paginate(10);
// Home Page Categories
$categories = DB::table('categories')->orderBy('category_name', 'desc')->get();
// Return
return view('welcome' , [ 'categories'=>$categories,'latest_posts'=>$latest_posts]);
}
Something strange happening when using eager loading.
For example i want the get all authors related with a user, and everyhing was working well, but when i use eager loading it doesnt work well.
Example:
Users:
- id;
- name
- ...
Authors:
- id
- user_id
- ...
Model User:
public function authorsProfile()
{
return $this->hasMany(Author::class, 'user_id', 'id');
}
My controller:
$user = Auth::user();
//Get all users and the authors that is related with it (Not working well)
dd( $user->with('authorsProfile')->get());
//Get all authors that is related with this user (Working well)
dd( $user->authorsProfile);
In my case is supposed to give me only the authors related with the current authenticated user, but for some reason when i try to use eagerloading for some reason is getting all users and there relation (authors)...
Does someone have a idea whats wrong?
Calling ->get() executes a whole new query that fetches all users.
You are looking for lazy eager loading:
$user->load('authorsProfile');
If you've already got the User loaded, using ->with() is not the correct approach. In your case, try ->load():
$user = Auth::user();
$user->load("authorsProfile");
dd($user->authorsProfile); // Should be a Collection
Technically, you don't even need to call ->load(), as attempting to access a relationship that wasn't loaded with ->with() will load it at that point:
$user = Auth::user();
dd($user->authorsProfile); // Should also be a Collection
To make it work like you have it coded, you'd need to call:
$user = Auth::user();
$user = User::with(["authorsProfile"])->where("id", "=", $user->id)->first();
dd($user->authorsProfile);
But, you can see why that would be inefficient; you'd be calling the database again to retrieve a record you already have.
So, lots of way to accomplish this. See what you can get working.
What I'm trying to do is to show the posts that have been saved by the user in the profile. I will try to explain it as good as possible refering to my code. So:
public function userProfil($id)
I have the profile function which get the data from userprofile table. and inside I have the following code for saved data:
$authed = User::find($id);
$savedarticles = $authed->mysaves;
$allsavings = DB::select("Select * from article where id=$savedarticles->id");
But this code does not work like this anyway. I can do this instead:
$authed = User::find($id);
$savedarticles = $authed->mysaves;
But when I try to get articles from article table with the article_id of mysaves, it does not work such as this:
$allsaved= DB::table('article')->where('id', $savedarticles->article_id);
the error it gives is like:
Property [article_id] does not exist on this collection instance.
although savearticle table has article_id I can output it without the line above and in view I get them as:
#foreach($savedarticles as $savedarticle)
<p>{{$savedarticle}}</p>
#endforeach
it gives me everything that is in the savearticle table and I can get do savedarticle->article_id and get article_id but can't get it in controller.
I am using Laravel 5.4.
The error message Property [article_id] does not exist on this collection instance. means you are trying to get an attribute of a single instance but from a collection.
For example the collection could be like
[$article1, $article2, $article3]
therefore what you tried to do is something similar to
[$article1, $article2, $article3]->article_id
You are trying to get an attribute from a collection instead of a single instance.
As for your query, you can use where in sql statement to search for rows that match any item in an array
$allsaved= DB::table('article')->whereIn('id', $savedarticles->pluck('article_id')->all());
What I have understood is that A USER has many POSTS and a POST belong to an article.
If this is true then you have to do following.
1: In USER model define a relation to get all posts. like below.
public function posts() {
// Foreign key will be a key that is stored in posts table and represent the user MAY BE: user_id
$this->hasMany(Posts::class, 'foreign_key', 'local_key')
}
This will allow you to get all posts belong to a user.
2: In posts, model defines a user relation like below.
public function user() {
$this->belongsTo(User::class, 'foreign_key', 'local_key');
}
This will allow you to get a post User;
3: Now in your controller you will have something like this.
public function show($user_id) {
// find a user with posts as eager loading(to avoid query again)
$user = User::with(['posts'])->where('id', $user_id)->first();
// get all posts that belong to this user
$posts = $user->posts;
}
In controller show($user_id) method you will have a user data as well as user posts data. Now if you want to get a post relations then simply define as below. let say a post belongs to an article as well.
4: In posts, model defines a relation to get an article.
public function article() {
// This will allow you to get a post artcle
$this->belongsTo(Article::class, 'foreign_key', 'local_key');
}
Now you can get the article as well while finding a user. please see below. I am rewriting controller show action to give you a better understanding.
5: Get a user with user_id
public function show($user_id) {
// find a user with posts as eager loading(to avoid query again)
// eager loading for posts & post child, this will give you NOSQL at runtime and all data will come from one query.
$user = User::with(['posts', 'posts.article'])->where('id', $user_id)->first();
// get all posts that belong to this user
$posts = $user->posts;
foreach($posts as $post) {
$article = $post->article; // Child relation of post.
}
}
Hope you will understand the flow, you have to make sure models relation to work it perfectly. If you need further help please let me know.
I have a database of two tables. One with blog posts and one with users, related by a user_id field in the post table. On my index page I have a table of the posts and I want to add the author to that however I want to display the user's name rather than their ID. I am trying to add an author field to my post objects like this in PostsController:
public function index() {
$this->set('posts', $this->Post->find('all'));
foreach ($this as $post){
$post['Post']['author'] = $this->User->findById($post['Post']['user_id']);
}
}
however this brings the error that I am calling findById on null. I am very new to php so I think my understanding of how to use the loop may be incorrect. Perhaps there is a better way which does not require the loop?
Controllers in CakePHP, by default, only load their own models. If you need an additional model at some point, you need to load it in manually.
That won't solve your problem though, because you're setting the result for the find() action straight into the view. You'll want to wait with that until you add the users to it. Oh, and you usually can't iterate through $this with foreach, unless your class implements an Iterator-like interface (which controllers should never have a reason to do)
public function index() {
// first load in the User model
$this->loadModel('User');
// store the posts in a local variable first
$posts = $this->Post->find('all');
// loop through the local variable, also keep the index so we can reference
// the post we're modifying
foreach ($posts as $index => $post) {
$post['Post']['author'] = $this->User->findById($post['Post']['user_id']);
// write the modified $post back into the $posts array
$posts[$index] = $post;
}
// **now** you can make $posts available to your view
$this->set('posts', $posts);
}
Once you have this sorted out, read up on linking models together. There's a way to set up your Post model so that it will automatically fill $post['Post']['author'] with the corresponding User, without you having to do that manually.
Better you specify the relation in model.
In Post Model initialize the relation between post and user
public $hasOne = 'User';
Now in controller use Contain() to get linked models data
$posts = $this->Post->find('all')->contain(['User']);
$this->set('posts', $posts);
You will get User object with each post record which you can use to get user name, you do not need to write a separate query to fetch the user name.