Laravel Eloquent Relationships 3 tables - php

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();
}

Related

Best Practice to update hasMany Relationships with laravel

Hello Actually am trying to create an app in which every project has some users i.e ProjectMembers.
here is project model with TeamMembers function.
class Project extends Model
{
use HasFactory;
function TeamMembers(){
return $this->hasMany(ProjectMember::class);
}
}
project members table schema.
Schema::create('projects_members', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('project_id')->nullable();
$table->unsignedBigInteger('user_id')->nullable();
$table->foreign('project_id')->references('id')->on('projects');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
Now for updating project members i have to first delete relationships from Project members and then saving new one. because i have added multiselect dropdown. $request->team_members have type array.
public function update(Request $request, $id)
{
// return $request;
$project = Project::findorfail($id);
$project->name = $request->project_name;
$project->details = $request->details;
$project->start_date = $request->start_date;
$project->end_date = $request->end_date;
$members = $request->team_members;
ProjectMember::where('project_id', $id)->delete();
$this->update_project_memebers($members, $project);
return redirect('/projects');
}
public function update_project_memebers($members, $project){
foreach ($members as $member_id) {
$project_member = new ProjectMember();
$project_member->project_id = $project->id;
$project_member->user_id = $member_id;
$project_member->save();
}
}
here am deleting cuz if someone created project with two members and when the he/she want to update then he/she can remove one member from multiselect then i have to delete relationship cuz he/she selected only one user.
I don't think it's a good practice, so can i achieve this same func. with another way?
thankyou.
First of all please make a proper naming convention of pivot tabel according to laravel and same for the model name too.
As of now the solution is
define relation as
Project
public function teamMembers()
{
return $this->belongsToMany(ProjectMember::class, 'projects_members', 'project_id', 'member_id');
}
ProjectMember
public function projects()
{
return $this->belongsToMany(Project::class, 'projects_members', 'member_id', 'project_id');
}
So now instead of deleting use sync() method. AS
$project->teamMembers()->sync($members);
Important docs,
https://laravel.com/docs/8.x/eloquent-relationships#syncing-associations

Laravel models and relations tickets with feedback and users

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.

Return result from one table

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.

Laravel ManyToMany Multiple

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

How can I represent this Game Owner Relationship in Laravel's Eloquent

I'm trying to tease out a logical problem that I'm having and I didn't know where else to ask!
I have two Objects whose relationship I'm trying to describe; the User and the Game. So, right now, I have that a User belongs to many Games, and that a Game belongs to many Users. What I'm trying to describe is the special instance when a User owns a Game. Presumably, this would simply be a column in the table for the owner_id. I am, however, struggling to establish how I can represent this in Eloquent. Do I need to create a new Object for the Game owner? Or can I use some kind of User role to describe this?
Game
class Game extends Eloquent
{
protected $guarded = array();
public static $rules = array();
// Game belongsToMany User
public function users()
{
return $this->belongsToMany('User');
}
// Need to identify the owner user.
}
User
class User extends Eloquent
{
protected $guarded = array();
public static $rules = array();
// User belongsToMany Game
public function games()
{
return $this->belongsToMany('Game');
}
}
I'm having difficulty even figuring out how to ask this in a clear and concise way, so if there's any more detail needed, please don't hesitate to ask.
What you need is thid table: games_owners. This is a migration schema for it:
Schema::create('games_owners', function($table)
{
$table->increments('id');
$table->integer('user_id');
$table->integer('game_id');
$table->timestamps();
});
This would be your User model:
class User extends Eloquent
{
protected $guarded = array();
public static $rules = array();
// User belongsToMany Game
public function games()
{
return $this->belongsToMany('Game', 'games_owners', 'user_id');
}
}
And you game model:
class Game extends Eloquent
{
protected $guarded = array();
public static $rules = array();
// Game belongsToMany User
public function users()
{
return $this->belongsToMany('User', 'games_owners', 'game_id');
}
// Need to identify the owner user.
}
And then you'll be able to do things like this:
$user = User::find(1);
foreach($user->games as $game) {
echo $game->name;
}

Categories