hi i am using a custom repository and I am getting comfortable with querying one table to retrieve data like so:
public function getAll()
{
// get all logged in users projects order by project name asc and paginate 9 per page
return \Auth::user()->projects()->orderBy('project_name', 'ASC')->paginate(9);
}
and in my controller I simply call
public function __construct(ProjectRepositoryInterface $project) {
$this->project = $project;
}
public function index()
{
$projects = $this->project->getAll();
echo View::make('projects.index', compact('projects'));
}
and my view is as so:
#if (Auth::check())
#if (count($projects) > 0)
#foreach ($projects as $project)
{{ $project->project_name }}
#endforeach
#else
<p>No records, would you like to create some...</p>
#endif
{{ $projects->links; }}
#endif
However within my projects table I have a status_id and a client_id and I want to retrieve records of this these tables with the logged in user but I am not sure how to structure my query, does anyone have any guidance?
According to the laravel documentation, In your project model you can add the following function:
class Project extends Eloquent
{
public function clients()
{
return $this->hasMany(Client::class);
}
}
In your client model you can then add the inverse of the relationship with the function:
class Client extends Eloquent
{
public function project()
{
return $this->belongsTo(Project::class);
}
}
Then you can retrieve the data with a function like:
$clients = Project::find(1)->clients;
Related
Here is the Controller code I have
public function index()
{
$ajobs = Job::all();
return view('jobs_all', ['jobs' => $ajobs]);
}
This shows all my Table Data. I have stored user id as another column named created_by
In the View, I get value by ID, how how can I get the Username from Users table.
#foreach ($jobs as $ajob)
{{ $ajob->created_by }} //Here instead of UserID, how can i get Username by matching the UserID with UsersTable ?
#endforeach
Add next method to your "Job" model:
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
now you can add ORM param "with" to your method "index":
public function index() {
$ajobs = Job::with('user')
->all();
return view('jobs_all', ['jobs' => $ajobs]); }
now we have access to user model fields, and you can show them this way:
#foreach($jobs as $ajob)
{{ $ajob->user->name }}
#endforeach
More info about laravel relations here: https://laravel.com/docs/8.x/eloquent-relationships#one-to-one
you can use laravel eloquent belongsTo relationship. in your Job model add the following method.
public function user()
{
return $this->belongsTo(User::class, 'created_by');
//assuming your user model name is User and both models are in the same namespace. if not, adjust according to your structure.
}
and then you can use this relationship to get the user name like
#foreach ($jobs as $ajob)
{{ $ajob->user->name }}
//name is the column name from the user table. change if necessary.
#endforeach
You can use relations but in fast way on your situation you can join your tables:
$user_id = DB::table('jobs')
->select('users.id')
->join('jobs', 'jobs.user_id', '=', 'users.id')
->get();
=> add on your job table as foreginId user
$table->timestamp('created_at')->useCurrent();
$table->foreignId('created_by')->constrained('users')->onUpdate('cascade')->onDelete('cascade');
**That Function add on job model**
public function getCreatedAttribute()
{
return ucfirst($this->user->name);
}
=>relationship add on job table
public function user()
{
return $this->belongsTo(User::class,'id','created_by');
}
=>created display your user name
#foreach ($jobs as $ajob)
{{ $ajob->created}}
#endforeach
=>listing controller
public function index() {
$jobs = Job::with(['user']);
return view('jobs_all', compact('jobs')); }
I have MyRoom.php and TotalCity.php in my project in which each room is categorizes inside a city
so that I did this in MyRoom.php
public function location()
{
return $this->belongsTo(TotalCity::class, 'location_id')->withTrashed();
}
and I did this in TotalCity.php
public function location()
{
return $this->hasMany(MyRoom::class , 'total_city_id')->withTrashed();
}
I have passed id with routes and controller like this
home.blade.php
id)}}">{{ $row->name }}
web.php
Route::get('/city/{id}/rooms/','SiteController#room')->name('room');
SiteController.php
public function room($id) {
$room = TotalCity::find($id)->location;
return view('frontend.pages.rooms', compact('room'));
}
rooms.blade.php
#foreach($room as $row)
<div class="room">
<img src="{{ asset(env('UPLOAD_PATH').'/' . $row['photoi1']) }}"/>
</div>
#endforeach
But this is not showing any rooms in any city while i have stored cities and rooms which comes under particular city in my database.
In the relationship method, you should mention foreign key and owner key as well,
for example in MyRoom.php:
public function location()
{
return $this->belongsTo(TotalCity::class, 'location_id', 'total_city_primary_key')->withTrashed();
}
you can read laravel documentioation for more detail.
foreignKey in TotalCity model is wrong :
public function location(){
return $this->hasMany(MyRoom::class, 'location_id')->withTrashed();
}
I strongly recommend you to change your model's names to City and Room. If you dont want to, make sure in both models you're connecting them to the correct table, you can achieve that using the $table variable in both models, like this:
$table = 'your_table_name';
This will make sure the table is connected right.
Also, you should make a few changes:
In your TotalCity model do this:
public function rooms()
{
return $this->hasMany(MyRoom::class , 'total_city_id')->withTrashed();
}
In your MyRoom model do this:
public function city()
{
return $this->belongsTo(TotalCity::class)->withTrashed();
}
In your SiteController do this:
public function room($id) {
$rooms = TotalCity::find($id)->rooms;
return view('frontend.pages.rooms', compact('rooms'));
}
In your View
#foreach($rooms as $room)
<h2>{{$room->name}}</h2>
<div class="room">
<img src="{{ asset(env('UPLOAD_PATH').'/' . $room['photoi1']) }}"/>
</div>
#endforeach
I have a blog and want to include the Users Name when shown to the public.
When creating the blog I make sure to include the user_id in the blogs table
In my Blog model I have the following:
public function users()
{
return $this->belongsTo(User::class);
}
In my Users model I have:
public function blogs()
{
return $this->hasMany(Blog::class);
}
In my Blog Controller I have:
public function index(User $user)
{
$users = User::get();
$blogs= DB::table('blogs')->where('user_id', '=', $users->id)->orderBy('id', 'DESC')->paginate(6);
return view('blogs.index',compact('blogs'));
}
Then in my view:
#foreach($blogs as $blog)
<h1>{{$blog->title}}</h1>
Source:{{$blog->users->first_name}} // This does not work
Source:{{$blog->first_name}} // This does not work either
#endforeach
I thought I could do something like this to show the names:
{{ $blogs->users->first_name }} {{ $blogs->users->last_name }}
But this isn't working either...
Try this:
#foreach($blogs as $blog)
<h1>{{$blog->title}}</h1>
{{$blog->user->first_name}}
#endforeach
And on your Blog Model
public function user()
{
return $this->belongsTo(User::class);
}
In your Blog controller the variable $blog needs to be $blogs. You also have extra characters (right parenthesis) in your Blade. It should be:
#foreach($blogs as $blog)
Source: {{ $blog->user->first_name }}
...
#endforeach
Blog Model
This function replaces the old "users" function, as only one user is returned (belongsTo is a singular relationship).
class Blog extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
User Model
public function blogs()
{
return $this->hasMany('App\Blog');
}
Controller Function
And, as such, you can cut down your controller code, including removing the redundant elements.
public function index(User $user)
{
$blogs = Blog::where('user_id', '=', $user->id)->orderBy('created_at','desc')->paginate(6);
return view('blogs.index', compact('blogs'));
}
The way you did is called Query Builder
$blogs= DB::table('blogs')->where('user_id', '=', $users->id)->orderBy('id', 'DESC')->paginate(6);
Query Builder does not support lazy loading, cause lazy loading is only supported for the Eloquent method
$blog->users->first_name
For Eloquent way you can try this instead:
$blogs = Blog::where('user_id', $user->id)->get()
foreach($blogs as $blog){
dd($blog->user); // you will get the user detail here
}
For lazy loading have a performance issue when come to load heavy data so to prevent lazy loading can use this
$blogs = Blog::with('user')->where('user_id', $user->id)->get()
For more information can look at Eloquent Relationship Documentation
For query builder, the only way to link your user is use join, which will be something like this
$blogs = DB::table('blogs')
->join('users', 'users.id', '=', 'blogs.user_id')
->get();
foreach($blogs as $blog){
dd($blog->first_name) // user first name
}
For more information can look at Query Builder Join
BlogController.php
public function index(){
$blogs = Blog::with('user')->get();
return view('blogs.index')->with('blogs',$blogs);
}
Blog.php
public function user()
{
return $this->belongsTo('App\User');
}
User.php
public function blogs()
{
return $this->hasMany('App\Blog');
}
I'm trying to show a list of contacts for the logged in user. But obviously I'm doing something wrong.
I get a error on the contacts list page:
Trying to get property 'name' of non-object
User.php
public function contacts()
{
return $this->belongsToMany(Contact::class);
}
Contact.php
public function users()
{
return $this->belongsToMany(User::class);
}
ContactsController.php
public function index()
{
//
$user = Auth::user();
$user_contacts = $user->contacts()
return view('contacts.list')->with('contacts', $user_contacts);
}
list.blade.php
#foreach ($contacts as $contact)
* {{ $contact->name }} <br>
#endforeach
Table schema:
contacts:
id
created_at
updated_at
name
address
users:
id
name
password
remember_token
created_at
updated_at
contact_user:
contact_id
user_id
If you want to access pivot properties of your many to many relationship table u can access with pivot
#foreach ($contacts as $contact)
* {{ $contact->pivot->name }} <br>
#endforeach
Also creates a relatioship between contact and users
public function contacts()
{
return $this->belongsToMany(Contat::class)->withPivot(['your', 'pivot','columns']);
}
Hope this helps
In your controller you have the following;
public function index()
{
$user = Auth::user();
$user_contacts = $user->contacts()
return view('contacts.list')->with('contacts', $user_contacts);
}
It needs to be the following;
public function index()
{
$user = Auth::user();
$user_contacts = $user->contacts
return view('contacts.list')->with('contacts', $user_contacts);
}
Using $user->contacts()(method) will return an instance of the query builder for that relationship, where as $user->contacts(property) will return a collection with results from a select query.
You must return your pivot table's data in the relation as below:
public function contacts()
{
return $this->belongsToMany(Contat::class)->withPivot(['your', 'pivot','columns']);
}
And you must get relation data like below:
$user_contacts = $user->contacts // Not $user->contacts()
I'm learning Laravel right now and i have following tables and resources (models, controllers, ect.):
tickets
- id
- title
- projectID
- statusID
projects
- id
- title
status
- id
- title
I have to make a list of my Tickets on the Startpage. Not nessesary to say that i need the Project- and Statustiltles and not the IDs. Currently i do:
Route::get('/', function()
{
$tickets = Ticket::all();
return View::make('layout')->with('tickets', $tickets);
});
My current output is:
tickets->id, tickets->title, tickets->projectID, tickets->statusID
The output i want is
tickets->id, tickets->title, tickets->projects->title, tickets->status->title
So i hope anyone can understand what i'm trying to ask here and maybe provide me some help. Thank you!
Resolution: I had to set the foreign_keys first in my DB. Then i used the relationships mentioned in the answers and it works fine.
My Model:
class Ticket extends \Eloquent {
protected $fillable = [];
public function project()
{
return $this->hasOne('Project', 'id', 'projectID');
}
public function status()
{
return $this->hasOne('Status', 'id', 'statusID');
}
}
My View:
#foreach($tickets as $key => $value)
...
<td>{{ $value->project->title }}</td>
<td>{{ $value->status->title }}</td>
...
#endforeach
If you configure you relationships correctly you can do that without problems using the Laravel Eager Loading feature, for example:
Eager Loading (Laravel docs)
Eager loading exists to alleviate the N + 1 query problem...
class Ticket extends Eloquent {
public function project()
{
return $this->belongsTo('Project', 'projectID', 'id');
}
public function status()
{
return $this->belongsTo('Status', 'statusID', 'id');
}
}
Now, just call the fields you want, for example:
foreach (Ticket::all() as $ticket)
{
echo $ticket->project->title;
echo $ticket->status->title;
}
Obs.: In your return object/array you can't see the relationships fields unless you do manual joins, etc. So, just configure your relationships and call the fields you want.
Sorry for my english
Define relationships specifying custom foreign keys (defaults would be status_id and project_id for your models):
// Ticket model
public function project()
{
return $this->belongsTo('Project', 'projectID');
}
public function status()
{
return $this->belongsTo('Status', 'statusID');
}
Then eager load related models:
$tickets = Ticket::with('project','status')->get();
// accessing:
foreach ($tickets as $ticket)
{
$ticket->status; // Status model with all its properties
$ticket->project; // Project model
}