Laravel - Backpack. Display field from other model - laravel

After many research I couldn't find the answer to my question.
I have a model "Station" with two fields : "name" and "city_id".
In my Station view (in the backpack admin panel) I would like to display city's name (in the model City).
Station and City model are correctly link with hasMany() and belongTo() methods.
How can I set my column in my crud controller to display the name instead of the city id ?
Thank for your help !

Station Model
<?php
[...] // Namespaces
Class Station {
[...]
public function city() {
$this->belongsTo('App\City');
}
}
City Model
<?php
[...] // Namespaces
class City {
[...]
public function station() {
$this->hasMany('App\Station');
}
}
Crud Controller
<?php
[...] // Namespaces
class CrudController {
public function sampleFunction() {
$stations = App\Station::with('city')->all();
return view('stations', compact('stations'));
}
}
View
Now you can loop the stations on your view like
<ul>
#foreach($stations as $station)
<li>{{ $station->city->name }}</li>
#endforeach
</ul>

You had wrong sight on backpack fields.
Take a look at here.
You can build a custom view and use this for your other model.
Can't add field from different table in laravel-backpack CRUD

Related

How to get information from 3 separate tables in Laravel

I have a table called users that stores user information and each user can have multiple business accounts that are stored in separate tables.
Models:
User:
id
name
UserProviderAccount:
id
user_id
bussiness_name
bussiness_tell
bussiness_address
UserCompanyAccount
id
user_id
company_name
company_size
UserInfluencerAccount:
id
user_id
name
website
follower_count
Tables Relations :
User :
public function providers(): HasMany
{
return $this->hasMany(UserProviderAccount::class);
}
public function companies(): HasMany
{
return $this->hasMany(UserCompanyAccount::class);
}
public function influencers(): HasMany
{
return $this->hasMany(UserInfluencerAccount::class);
}
I want to display the user's business accounts of all three types at once.
How do I do this?
You simply need to load and call the relationships as follows:
UserController: sample controller and function
public function show(User $user){
//Here we will load all of the relationships for the specific user
$user->load('providers', 'companies', 'influencers');
//Assign the providers from user->providers
$providers = $user->providers;
//Assign the companies from user->companies
$companies = $user->companies;
//Assign the influencers from user->influencers
$influencers = $user->influencers;
//Send all of the data to the view
return view('users.show', compact('user', 'providers', 'companies', 'influencers'));
}
users.show View: simplified version to show you concept.
<p>{{$user->name}}</p>
<p>The providers:</p>
<ul>
#foreach($providers as $provider)
<li>{{$provider->bussiness_name}}</li>
<li>{{$provider->bussiness_tell}}</li>
<li>{{$provider->bussiness_address}}</li>
#endforeach
</ul>
<p>The companies:</p>
<ul>
#foreach($companies as $company)
<li>{{$company->company_name}}</li>
<li>{{$company->company_size}}</li>
#endforeach
</ul>
<p>The influencers:</p>
<ul>
#foreach($influencers as $influencer)
<li>{{$influencer->name}}</li>
<li>{{$influencer->website}}</li>
<li>{{$influencer->follower_count}}</li>
#endforeach
</ul>

Laravel how to define relationship based on two models or columns?

I have the following:
//users table
id
name
email
remeber_token
role_id
//roles table
id
name
//products table
id
name
//product_prices
role_id
product_id
price
The price of the product will vary depending on the user role, how to define the correct relationship so in blade I can do something like:
$product->price
and that will return the correct price depending on the user and the product?
I believe that when you say the user role, you refer to the role of the authenticated user.
The easiest approach is to define a HasOne relationship on the product model:
class Product
{
public function price()
{
return $this->hasOne(Price::class)->where('role_id', auth()->user()->role_id)
}
}
So from the view, you can simply say:
// Lets use optional() because there may not be any price for that product and user.
optional($product->price)->price
If there are many products involved, then using sub queries would make more sense.
class ProductsController extends Controller
{
public function index()
{
$products = Product::addSelect(['right_price' => Price::select('price')
->whereColumn('product_id', 'products.id')
->where('role_id', auth()->user()->role_id)
->limit(1)
])->get()
return view('products.index', compact('products'));
}
}
And then in the view:
#foreach($products as $product)
<p>{{$product->right_price}}</p>
#endforeach
For more info, pls check out this article.

Laravel 5 has one relationship

I have two tables: drugs table and formulations table. The drugs table has fields id, name, quantity and formulation_id. The formulations table has fields id and name.
What relationship should I use to get the drugs records including the name of the formulation.
Note that 1 drug record has only one 1 formulation record.
I have tried using hasOne relashionship but doesn't work:
My view looks as follows:
#foreach($drugs as $drug)
<li>
<a class="padded-list" href="">{{$drug->name}} ({{$drug->formulation->name}})</a>
</li>
#endforeach
My model relationship in the the Drug model looks as follows:
public function formulation()
{
return $this->hasOne('App\Formulation');
}
Your formulation() method in your Drug model should be:
public function formulation()
{
return $this->belongsTo('App\Formulation');
}
If you call $drug->formulation return Eloquent Collection, you can't get name
You should call $drug->formulation()->first()->name
Good day, formulation() in Drug model shoud be
public function formulation()
{
return $this->belongsTo('App\Formulation');
}
If one formulation can have many drugs, Drugs() in Formulation model shoud be
public function drugs()
{
return $this->HasMany('App\Drug');
}
You can get formulation by this way
$drug->formulation()->first()->name
or
$drug?->formulation?->name
in new php versions

How to safely access other users and other model's records inside Blade template

I have 3 models in my app Users, Sales and Plans, when I render sales for each customer (due to storing) I only get id's for other users and models related to that sale (like account manager, owner, plan), now I'm trying to use those ID's inside blade to get names or other rows based on ID and model. Here is the show function:
public function show($id) {
$user = User::find($id);
$sales = Sale::where('customer_id', '=', $id)->get();
return view('profiles.customer', ['user' => $user, 'sales' => $sales]);
}
And in blade I get all those sales like:
#foreach ($sales as $sale)
<li>
<i class="fa fa-home bg-blue"></i>
<div class="timeline-item">
<span class="time"><i class="fa fa-clock-o"></i> {{$sale->created_at->format('g:ia, M jS Y')}}</span>
<h3 class="timeline-header">{{$user->name}} became a customer</h3>
<div class="timeline-body">
<p>Date: {{$sale->sold_date}}</p>
<p>Price: {{$sale->sale_price}}</p>
</div>
</div>
</li>
#endforeach
So inside each record I have like "account_manager_id", "agent_id", "owner_id", "plan_id".
Currently I have this solved by adding public static function (this is for users, have same function for Plan model as well) in Sale model class:
public static function getUser($id) {
return User::where('id', $id)->first();
}
And I'm using it like this in Blade:
Account manager: {{$sale->getUser($sale->account_mgr_id)->name}}
Is this the safest and best way to do it? Or there is something I'm overlooking here?
You need to add relationships in your Sales Model.
class Sales extends Eloquent {
.....
.....
public function accountManager() {
return $this->hasMany('App\User', 'account_manager_id');
}
public function agents() {
return $this->hasMany('App\User', 'agent_id');
}
public function owner() {
return $this->hasOne('App\User', 'owner_id');
}
}
Now $sales->agents will give you a user with agent_id as id in User table.
Update your hasOne, hasMany relationships as your need. Laravel Documentation.
From your blade template, your access your AccountManager as
#foreach($sales->accountManager as $manager)
Name: {{ $manager->name}}
#endforeach
I think you could use Eloquent relationships. Taking your example, you should define relationship in your User model:
<?php
class User extends Eloquent {
public function sales() {
return $this->hasMany(Sale::class, 'customer_id');
}
}
Then, whenever you need to get sales of that user (entries, that relate via customer_id column), just simply do
<?php
$user = User::find($id);
$sales = $user->sales;
This is very fun when when you have to print out list of users that have sales, for example
<?php
public function showUsersWithSales() {
$users = User::with('sales')->get();
return view('users-with-sales', compact('users'));
}
users-with-sales.blade.php example:
#foreach ($users as $user)
User: {{ $user->name }}<br>
Sales:<br>
#foreach ($user->sales as $sale)
{{ $sale->amount }} {{ $sale->currency }} # {{ $sale->created_at }}<br>
#endforeach
<hr>
#endforeach
It would print all users with their sale amount and currency, followed by date when it was created.
This sample takes into account, that your User model has name attribute and your Sale model has amount, currency, created_at and customer_id fields in your database.
To reverse the action, say you have a sale and want to know who made it, just simply define a relationship!
<?php
class Sale extends Eloquent {
public function customer() {
return $this->belongsTo(User::class, 'customer_id');
}
}
Hope that helps!
Eloquent Relationship is your friend, https://laravel.com/docs/5.2/eloquent-relationships and you can solve your problem easily.
Suggestion is to remove all those function access and control from view and put it somewhere else. This will be good habit for you so you can avoid the infamous fat view.

Laravel: check relationship

Please bear with me, i'm bad at explaining things and i don't think the title suits my problem.
I have a User model and a Course model.
These models have a manytomany relationship.
There currently are 4 Courses, but the User only has a relationship with 2 of them (lets say Course 1 and 3).
On a certain page i'd like to output all Courses, and highlight the Courses the User has a relationship with, so it can view the Course. So, Course 1 and 3 will be highlighted, while Course 2 and 4 will be faded.
User model:
public function courses()
{
return $this->belongsToMany('App\Course');
}
Course Model:
public function users()
{
return $this->belongsToMany('App\User');
}
The Controller
public function index()
{
$member = $this->auth->user();
$courses = $this->courserepository->getAllCourses(); // Course 1,2,3,4
$member_courses = $member->courses; // Course 1,3
// Logic to filter courses which are in a relationship with the User
return view('member.course.index', compact('member', 'courses'));
}
I wish i had some more code, but i have deleted most of it since it was not working as suspected.. I'm looking for someone to point me in the right direction.
In controller replace:
$member = $this->auth->user()->with('courses');
then in view:
<ul>
#foreach($courses as $course)
<li#if(in_array($course['id'], array_column($member['courses'], 'id'))){{' class="highlighted"'}}#endif>
{{$course->name}}
</li>
#endforeach
</ul>

Resources