Display name of table instead of its id Laravel - php

I have 2 tables, tn_project has id name cv_id_project and tn_activity has id name id, i want to get the name of the project which is cv_project_name rather its id.
Basically when i click add activity i have select option to choose which project that i use, i manage to get the id of selected project but i want its name(i can select up to 3 project in a single activity)
Model
<?php namespace Activity;
use Illuminate\Database\Eloquent\Model;
class Activity extends Model {
protected $table = 'tn_activity';
public $timestamps = false;
public function projectModel(){
return $this->hasMany('Activity\Project','cv_id_project','id');
}
}
VIEW
#foreach($query as $result)
<td>{{$result->projectModel->cv_project_name}}</td>
#endforeach
Controller
public function index(){
return view('landing-page')
->with('title','Landing Page')
->with('query',Activity::with('projectModel')->get())
->with('projects',Project::all());
}
usually it's work but i don't know what makes it error
and then this error occured
Undefined property: Illuminate\Database\Eloquent\Collection::$cv_project_name (View: C:\xampp\htdocs\PKL\netxcel-2-backup2\resources\views\landing-page.blade.php)

Your Activity projectModel is a collection, because it has hasMany relationship. If it's really true, you should get the project name like this.
#foreach ($result->projectModel as $project)
<td>{{$project->cv_project_name}}</td>
#endforeach
However, if it shouldn't have hasMany relationship than you should change the hasMany part

Related

Hello i m stuck with Laravel eloquent relationship

i have two tables deals and products, on product table i just have product description whic can be assigned to one than more deals , now i want to display product description on deal page,but my relation is not working correctly,
product table
deal table
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
//
protected $guarded=[];
public function deals()
{
return $this->belongsTo(Deal::class,'product_slug','product_id');
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Deal extends Model
{
//
protected $guarded=[];
public function products()
{
return $this->hasMany(Product::class,'product_slug','product_id');
}
}
this is how i m calling the function in controller
public function index()
{
$title='Today Deal';
$deals=Deal::with('products')->get();
// dd($deals);
// return;
return view('welcome',compact('title','deals'));
}
i can see the product data when i do dd but on view i m getting this error when i access the product data
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$title (View: D:\xampp\htdocs\bargin\resources\views\welcome.blade.php)
this how i acces the the product data inside the deal loop
<p>{{$deal->products()->title}}</p>
The problem is inside your loop. <p>{{$deal->products()->title}}</p>.
When you access a relationship using the function call, products(), you are actually returning an instance of the relationship to where you can add query methods to.
For example, you can use $deal->products()->where(...)->get().
In order to access the actual products, you just use $deal->products.
#foreach($deal->products as $product)
{{ $product->title }}
#endforeach

Laravel Eloquent Model change table name on runtime in a related instance

I am new to Laravel and also asked the question on Laracast without any success so far.
Here is my problem: I have a database layout something like this:
Table: categoryA_products
Table: categoryB_products
Table: categoryC_products
and per default the Laravel user table:
Table: user
I have create a two Laravel Eloquent models:
Product:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
// protected $table = '';
public function users()
{
return $this->belongsTo( User::class );
}
}
User:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function products()
{
return $this->hasMany( Product::class );
}
}
As each product has a different table name I would normally create 1 model for each table but as they are all similar I would like to define the model table name at runtime.
I know I can do this with "$product->setTable()" but as I use the "newRelatedInstance" class from Laravel (hasMany and belongsTo) I cannot initiate the product class and set the table.
Is there a workaround for this?
Yes, I am aware that I could create a category table and link the products to each category but this is a fictional database model. There is a reason for this approach and I can explain it more in detail if needed. That said it make sense for this sample but I cannot use it for the live database.
I have a working solution with a model for each "category" but this is very messy.
Any help would be appreciated.
Since you're unable to load the relations, you could try referencing and re-initializing them like:
$relations = $product->getEagerLoads();
$attributes = $product->getOriginal();
table_name = 'categoryA_products'; // or categoryB_products or categoryC_products
$product->newQuery()
->newModelInstance($attributes)
->setTable($table_name)
->setEagerLoads($relations)
->...

Laravel Proper Relationship

So i have a 3 tables. Users-Inventory-Item. User hasmany Items, so far i have no problem. I can reach Items of User with this relationship.
Item table contains : user_id, item_id
So my problem is to reach item info of the Inventory of the User by item_id(which will find id of Item table and bring the info). I couldn't manage it, I need you advices about which relations would be the proper for my aim.
Models
class User extends Authenticatable
{
public function Inventory(){
return $this->hasMany('App/Item');
}
class UserItem extends Authenticatable
{
public function Item(){
return $this->hasMany('App/Item');
}
Code in my controller
public function profile(){
$inventory_items = Auth::user()->Inventory;
return view('profile', compact('inventory_items'));
}
So i can get User's items with these code but. When i would like to get item info via this $inventory_items->item its not working. I think this is because of relationship mistakes of mine.
Codes in Profile
#foreach($inventory_items as $inventory_item)
{{$inventory_item->Item}}<br><br>
#endforeach
Error
(2/2) ErrorException Class 'App/Item' not found (View:
C:\xampp\htdocs\X-GOTL\resources\views\profile.blade.php)
I think that there is a few errors in your code, no? See my inline comments. Also, you seem to be forgetting that there are many inventories per user and many items per inventory so you need a double-foreach loop.
class User extends Authenticatable
{
# There are many inventories per user so put a plural 's' on items
public function inventories()
{
# This should NOT be App\Item
return $this->hasMany('App\Inventory');
}
...
# This should NOT be UserItem but Inventory, right? (Remember to rename that file too!)
class Inventory extends Authenticatable
{
# There are many items per inventory so put a plural 's' on items
public function items()
{
return $this->hasMany('App\Item');
}
Also your error tells you that you have not created a file App\Item so run php artisan make:model Item.
then in your controller do:
public function profile()
{
$inventories = Auth::user()->inventories;
return view('profile', compact('inventories'));
}
and in your view
#foreach($inventories as $inventory)
#foreach($inventory->items as $item)
{{ $item->name }} or {{ $item->id }}
#endforeach
#endforeach
Dev tend to make mistake \ (correct) and / (wrong).. ErrorException Class 'App/Item' show it cant find 'App/Item' which actually wrong syntax
return $this->hasMany('App/Item');
change to
return $this->hasMany(Item::class);
So guys actually i found the answer i needed. I just needed to create pivot table to make connection between Users and Items. So if someone will have same problem he can watch this video https://www.youtube.com/watch?v=akKWC_vP7sE . Thanks to you for your answers anyways!

Eloquent triple relation

I'm having a hard time understanding on how to model a triple relation in Laravel.
I have 3 models: User, Tour and Photo
Each tour has users associated with it and all users can post photos. Which means the database looks something like this:
id , tour_id, user_id, photo_id
This way I know which user posted which photo for which tour. My question is, how do I model this in Eloquent?
Update Based on your last comment.
The simplest answer to your question is by using relations belongsToMany and hasMany.
Let me explain.
You need 4 table users, tours, tour_user and photos.
users table contain id,name
tours table contain id,name,
tour_user table contain id,tour_id,user_id
photos table contain id,name,user_id,tour_id
Why belongsToMany ? because each user has more than one tour and each tour has more than one users. So we link both tables by using a third table tour_user. It also helps in normalization.
Now that we have examined the table structure for the relationship, let's define it on the User model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function tours()
{
return $this->belongsToMany('App\Tour');
}
/* To retrieve photos of a user */
public function photos()
{
return $this->hasMany('App\Photo');
}
}
Tour model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tour extends Model
{
public function users()
{
return $this->belongsToMany('App\User');
}
/* To retrieve photos of a tour*/
public function photos()
{
return $this->hasMany('App\Photo');
}
}
Now Photo model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Photo extends Model
{
public function users()
{
return $this->belongsTo('App\User');
}
public function tours()
{
return $this->belongsTo('App\Tour');
}
}
Now let find all tour of a specific user by using
public function show($id)
{
$user = User::find($id);
return view('show')->withUser($user) ;
}
Now in show view, page lets extract all tours of that user and his photos
#foreach($user->tours as $tour)
{{ $tour->name }}
#foreach($tour->photos as $photo)
#if($user->id == $photo->user_id)
{{ $photo->name }}
#endif
#endforeach
#endforeach
You should have: one to many Tour > user and
one to many User > Photo
include this function in your Tour model.
public function allusers()
{
return $this->hasMany(User::class);
}
and this in your User model.
public function allphotos()
{
return $this->hasMany(Photos::class);
}
Then you can get a tour $tour = Tour::find(1);
and just use the function to get the users with this:
$usersOnTour = $tour->allusers();
First make sure you have a user_id foriegn key field in your tour model and 'photo_id' foriegn key field in your user moel
the trick is to have user model with a hasOne/hasMany relationship with photo model and then have tour model with a hasOne/hasMany relationship with the user model.
1 - first in your user model define a relationship like this
public function photo()
{
return $this->hasOne('App\Photo');
}
2 - In your tour model define a hasMany relationship like this
public function users()
{
return $this->hasMany('App\User');
}
so when you fetch a tour model like
$a = tour::All();
you can do
$a->users->'field_in_user_table'
or
$a->users->photo; // to get the photo field value from photo table

how to use a simple Relationships in laravel

I have two tables like below:
users table:
id - fname - lname
users_projects table:
id - user_id - title
my models are inside a directory called Models:
Users model :
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Users extends Model
{
//
public function usersProjects()
{
return $this->belongsTo(UsersProjects::class);
}
}
UsersProjects model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UsersProjects extends Model
{
protected $table = 'users_projects';
//
public function users()
{
return $this->hasOne(Users::class);
}
}
now, I want to show last projects :
$projects = UsersProjects::limit(10)->offset(0)->get();
var_dump($projects);
return;
but my var_dump shows last projects ! I want to have fname and lname ! where is my wrong ?
I think you may have your relationships set up a little wrong. If a user can have more than one project, in your user model ...
public function usersProjects()
{
return $this->hasMany(UsersProjects::class);
}
You might want to use a little simpler naming too ...
public function Projects()
{
return $this->hasMany(UserProject::class);
}
(or simply Project if you don't have any other "Project" models)
The in your "Project" class ...
public function User()
{
return $this->belongsTo(User::class);
}
(assuming you rename your model to User instead of "Users". Your table name should be "users" but a model is by nature a singular object. So it's appropriate to call it "User" - and your UsersProjects model should just be UserProject or just Project)
Now if you call the method something other than "User" you will have to add the foreign key name ...
public function SomeOtherName()
{
return $this->belongsTo(User::class, 'user_id');
}
Then ...
$projects = Project::with('User')->limit(10)->offset(0)->get();
Will return a collection of projects with the User eager-loaded. (assuming you have renamed your UsersProjects model to "Project")
#foreach($projects as $project)
...
First Name: {{ $project->User->fname }}
...
#endforeach
Could you specify the relationships between the tables? (one to one, one to many) at first sight, I think that the relations are wrong

Categories