I have two tables:
users
{ id, username }
items
{ id, user_id }
In laravel, how would I appropriately return the username on an items permalink?
For example:
item #39 by JohnSmith
I tried the following:
$items = DB::table('items')->where('id', '=', 39)->first();
$username DB::table('users')->where('id', '=', $items->user_id)->first();
item #{{ $items->id }} by {{ $username }}
Create two models in your models directory:
// User Model (app/models/User.php)
class User Extends Eloquent {
public function items()
{
return $this->hasMany('Item');
}
}
// Item Model (app/models/Item.php)
class Item Extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
Now you may use in your controller, something like this:
$item = Item::with('user')->find(39);
$username = $item->user->username;
If you are using Eloquent Models you could simply do
$item = Item::find(39);
$username = $item->user->username;
This of course requires you to have your relationships defined properly in both the User and Item model.
Related
I have three db tables. The first is PROJEKTS, the second table is USERS, and the third table is ACTIVITIES. The tables are related. There are multiple users under each project, and there are activities under each user.
A similar project is addressed here: Laravel Eloquent Relationships on 3 tables
I need Laravel Controller. Load only one specific project with users where each user can have activities.
class Projekts extends Model
{
public function user()
{
return $this->hasMany('App\User');
}
}
class User extends Authenticatable
{
public function activity()
{
return $this->hasMany('App\Activities');
}
}
Use this:
$projekt = Projekts::with('user.activity')->find($id);
foreach($projekt->user as $user) {
foreach($user->activity as $activity) {
}
}
This works for me. I want to know if there is a simpler code.
$form = $request->all();
$newproject = \App\Projects::create( $form );
$newproject_Id = $newproject->id;
foreach ($form['items'] as $item) {
$user= new \App\User;
$user->projects_id = $novafaktura_Id;
$user->nic = $item['name'];
$user-> ...and other
$user->save();
}
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 am trying to grasp the concept of Eloquent ORM by creating a ticketing system at the moment. What I am trying to achieve is:
The tickets with the user who posted the ticket
The feedback belonging to the ticket and the user who entered the
feedback
This is what I have right now:
// TicketController.php
public function index()
{
$tickets = Ticket::with('feedback')->with('user')->orderBy("created_at", "desc")->get();
//dd($tickets);
return View::make('modules.helpdesk.index')->withTickets($tickets);
}
And the following models
// Ticket.php
class Ticket extends Eloquent {
protected $table = 'helpdesk_tickets';
public function feedback()
{
return $this->hasMany('Feedback');
}
public function user()
{
return $this->belongsTo('User');
}
}
// Feedback.php
class Feedback extends Eloquent {
protected $table = 'helpdesk_tickets_feedback';
public function ticket()
{
return $this->belongsTo('Ticket');
}
}
// User.php
class User extends Eloquent {
protected $table = 'users';
public function ticket()
{
return $this->belongsTo('Ticket');
}
}
What I have now is the tickets, their related feedback and user who created the ticket. What I am trying to achieve now is to also get the user who created the feedback.
You need to fix the relation:
// User model
public function tickets()
{
return $this->hasMany('Ticket'); // adjust namespace if needed
}
Next add the relation:
// Feedback model
public function user()
{
return $this->belongsTo('User'); // namespace like above
}
then use eager loading:
// it will execute 4 queries:
// 1st for tickets
// 2nd for feedback
// 3rd for feedbacks' user
// 4th for tickets' user
$tickets = Ticket::with('feedback.user', 'user')->latest()->get();
you can then access the relations in a loop, like below:
#foreach ($tickets as $ticket)
{{ $ticket->title }} by {{ $ticket->user->name }}
#foreach ($ticket->feedback as $feedback)
{{ $feedback->content }}
#endforeach
#endforeach
What you want to do is create nested relations, just like Ticket add a belgonsTo relation on feeback
When you want to use it you can chain relations using the dot notation feedback.user
The code
// Feedback.php
class Feedback extends Eloquent {
protected $table = 'helpdesk_tickets_feedback';
public function ticket()
{
return $this->belongsTo('Ticket');
}
public function user()
{
return $this->belgonsTo('User')
}
}
// TicketController.php
public function index()
{
$tickets = Ticket::with('feedback')->with('user')->with('feedback.user')->orderBy("created_at", "desc")->get();
//dd($tickets);
return View::make('modules.helpdesk.index')->withTickets($tickets);
}
EDIT:
Even though this would work, it will execute more queries than needed. See Jareks answer.
Original Answer:
First of all you need to get your relationships straightened, in User.php you should call the user relationship with HasMany.
public function ticket() {
return $this->hasMany('Ticket');
}
In modules.helpdesk.index you should now have a Ticket Collection since your attaching the $ticket variable to the view.
If you loop through this collection with a foreach loop then what you should get is a model each loop:
foreach($tickets as $ticket) {
// Prints the name property of the Ticket model
print $ticket->name;
// Since a ticket only belongs to ONE user then that means that you are trying to fetch a model
// What we're doing here is getting the User model via the relationship you made in the model Ticket.php and then getting the name.
print $ticket->user()->first()->username;
// Since a ticket can have MANY feedbacks that means were fetching a collection
// which needs to be broken down to models so we do that looping the collection.
// Here we are doing the same thing as with the User model except with a collection.
foreach($ticket->feedback()->get() as $feedback) {
$feedback->text;
}
}
You should definitely check out the Laravel API and see Collection and Model there. http://laravel.com/api/ You get alot of help from there when you get stuck, trust me :)
I hope this answered your question.
There are three tables.
users:
- ...
- some_param
admins:
- ...
- club_id
- some_param
clubs:
- id
- title
Each user can have multiple admins (related by some_param), each admin can have multiple clubs, and I want to get each club's title.
So I defined a relations:
class User extends Eloquent {
public function admins() {
return $this->hasMany('Admin', 'some_param', 'some_param');
}
}
class Admin extends Eloquent {
public function clubs() {
$this->hasMany('Club', 'id', 'club_id');
}
}
And want to use it in template:
#foreach($user->admins as $admin)
#foreach($admin->clubs as $club)
{{ $club->title }}
#endforeach
#endforeach
But I'm getting an error: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation at line #foreach($admin->clubs as $club).
What's I am doing wrong? Thank you in advance.
In your following function:
public function clubs() {
$this->hasMany('Club', 'id', 'club_id');
}
You didn't return so use return like this:
public function clubs() {
return $this->hasMany('Club', 'id', 'club_id');
}
Also, when getting User collection in $user variable, try to use eager loading, for example:
$user = User::with('admins.clubs')->find(1);
This will reduce the queries.
I have 3 models: User, Role, Tool where each user could have many roles, and each role could have many tools.
The many to many relationships work well in each case. I can access:
User::find(1)->roles
Tool::find(1)->roles
Role::find(1)->tools
Role::find(1)->users
My tables are:
users
id
name
roles
id
name
tools
is
name
role_user
id
role_id
user_id
role_tool
id
role_id
tool_id
In each model:
//In User Model
public function roles()
{
return $this->belongsToMany('Rol');
}
//In Role Model
public function users()
{
return $this->belongsToMany('User');
}
public function tools()
{
return $this->belongsToMany('Tool');
}
//In Tool Model
public function roles()
{
return $this->belongsToMany('Rol');
}
I need to get all the tools of a single user like: User::find(1)->roles()->tools. How can I do that?
Get all the roles of the user, then in a loop you get all tools of the role and merge them to an array where you store all tools.
$tools = array();
foreach(User::find(1)->roles as $role)
$tools = array_merge($tools, $role->tools->toArray());
This runs a query for every iteration, so for better performance you should use eager loading.
$tools = array();
foreach (User::find(1)->load('roles.tools')->roles as $role) {
$tools = array_merge($tools, $role->tools->toArray());
}
Now you can place this to a function called tools() in your User model.
public function tools()
{
$tools = array();
foreach ($this->load('roles.tools')->roles as $role) {
$tools = array_merge($tools, $role->tools->toArray());
}
return $tools;
}
You can call it like this: User::find(1)->tools().
I don't think that the framework has a better solution. One other method is to use the Fluent Query Builder and create your own query but I don't see how that would be better.
Define a hasManyThrough relationship in User::find(1)->roles()->tools
class User extends Eloquent {
public function tools()
{
return $this->hasManyThrough('Tool', 'Role');
}
}
Then you can access straight forward:
$user->tools