laravel 5.7 many to many with custome table name - laravel

Goods Model
class goods extends Model
{
protected $table = "goods";
public function sales(){
return $this->belongsToMany('App\sales', 'sales_details', 'goods', 'sales');
}
}
Sales Model
class sales extends Model
{
protected $table = "sales";
public function goods(){
return $this->belongsToMany('App\goods','sales_details','sales','goods');
}
}
i also make this model but i don't know if i ever need it or not
class salesDetail extends Model
{
protected $table = "sales_details";
}
my controller
public function test()
{
$goods = goods::all();
return view('test',compact('goods'));
}
my test.blade.php
#foreach($goods as $data)
<li><strong>{{ $data->name }}</strong> - {{ $data->company->kind }} {{ $data->company->name }}</li>
<p>{{ $goods->sales }}</p>
#endforeach
i connect goods table with sales table with many to many without following laravel naming.
This is my table contents
goods
-id
-name
sales
-id
-date
sales_details
-goods
-sales
-qty
-price
and i couldn't make it work. i just wanted to show the result like this
sales -id
sales - date
goods - name
sales_details - qty
sales_details - price
this should be the result

In your #foreach loop you're trying to access sales on the collection of goods rather than the instance in the loop. Also, because the sales() relationship is a belongsToMany (many-to-many) you're going to get a collection and not a single instance so you're going to need to loop through them as well e.g.
#foreach($goods as $data)
<li>
<strong>{{ $data->name }}</strong> - {{ $data->company->kind }} {{ $data->company->name }}
#foreach($data->sales as $sale)
<p>{{ $sale->date }} - {{ $sale->pivot->qty }}</p>
#endforeach
</li>
#endforeach
To access data from your pivot table you will first need to tell Laravel to include that information in the relationship:
public function sales()
{
return $this->belongsToMany('App\sales', 'sales_details', 'goods', 'sales')
->withPivot('qty', 'price');
}
You should also add the withPivot method to the good() relationship in the sales class as well.
Then you'll be able access the information from the pivot property. This is happening in the example above with {{ $sale->pivot->qty }}.
Many to many docs (scroll down to Retrieving Intermediate Table Columns )

Related

How to included joined data in a loop

I am displaying a list on my blade view which contains data from the display table: name, school and IP.
The school is saved as a school id in this table.
The Schools table contains the list of ids and related schools.
I want to use the school names from the schools table and display them on my blade view.
I can get this data separately.
This gets all the data from the display table
$records = DB::table('display')->paginate(10);
This gets all the school name from the schools table.
$schools = DB::table('schools')
->join('display', 'schools.id', '=', 'display.school')
->select('schools.name')
->get();
To display the data from the display table I'm using a foreach loop.
#foreach ($records as $record)
{{ $record->name }}
{{ $record->school }}
{{ $record->ip }}
#endforeach
I don't know how to insert the school name into the space where currently $record->school appears. $record->school displays the school ID, but I want to display the school name which is saved in the school table.
Display model
public function school()
{
return $this->belongsTo('App\School');
}
School model
public function display()
{
return $this->hasMany('App\Display');
}
If you have models and Eloquent relations, you can simply use it:
Controller
$records = Display::with('school')->paginate(10);
Blade view
#foreach ($records as $record)
{{ $record->name }}
{{ $record->school->name }} <!-- school name via relation -->
{{ $record->ip }}
#endforeach
Display Model
class Display extends Model
{
public function school()
{
return $this->hasOne('App\School');
}
}
You really should be using Eloquent as it makes life so much easier. However, using DB, you need code similar to below, where you are joining schools as a relationship to display.
$records = DB::table('display')
->join('schools', 'schools.id', '=', 'display.school')
->paginate(10);
#foreach ($records as $record)
{{ $record->name }}
{{ $record->schools->name }}
{{ $record->ip }}
#endforeach

Property does not exist on this collection instance

I have a Client model that hasMany Appointment models. And an Appointment belongs to a Client. I am trying to return results that show me the client's name as well as their list of appointments on an index blade. Here is my code so far:
Client Model
public function appointment()
{
return $this->hasMany(Appointment::class);
}
Appointment Model
public function client()
{
return $this->belongsTo(Client::class);
}
Controlller
$clients = Client::with('appointment')->get();
//dd($clients);
return view('scheduler')->withclients($clients);
Blade
#foreach($clients as $client
{{ $client->name }}
{{ $client->appointment->id }}
#endforeach
How can I print $client name and their list of appointments? I have tried other help regarding this issue but I am not clear where I am going wrong.
So you relationship is a One-To-Many relationship. You have a lot of appointments then.
You can iterate over the clients list first and in the inner loop over the appointments:
#foreach($clients as $client)
{{ $client->name }}
#foreach($clients->appointment as $appointment)
{{ $appointment->id }}
{{ $appointment->name }}
#endforeach
#endforeach
Anyway, it might be easier to go over the appointment model, because it's in relation to exactly one client:
#foreach(Appointment::all() as $appointment)
{{ $appointment->name }}
{{ $appointment->client->name }}
#endforeach

Laravel get posts by category

I'm trying to figure out how to get all the posts for a category using Laravel Eloquent 5.3.
I have three tables..
**Posts**
id | title | text
**Term_relationships**
term_id | post_id
**Terms**
id | name
Eloquent Models
class Term extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post', 'term_relationship');
}
}
class Post extends Model
{
public function terms()
{
return $this->belongsToMany('App\Term', 'term_relationship');
}
}
class Term_relationship extends Model
{
}
I've tried with for example
Term::where('name', $category)->posts->get();
Easy,
if you want Posts with Terms do this
$data = App\Post::with('terms')->get();
in your view :
#foreach($data as $post) // will loop over posts and show title
<div>{{$post->title }} </div>
#foreach($post->terms as $term)
<div> {{ $term->title }} </div> // will loop and echo all terms for current post
#endforeach
#endforeach
if you want Terms with posts do this
$data = App\Term::with('posts')->where('name', $category)->get();
in your view
#foreach($data as $term) // will loop over terms and show title
<div>{{$term->title }} </div>
#foreach($term->posts as $post)
<div> {{ $post->title }} </div> // will loop and show all posts in each term
#endforeach
#endforeach
i think the seconds way suits your needs better since int he first example u will need to use wherehas and a closure

Laravel 5.3 access hasone in elequant from view

I'm trying to access a relations table from a collection of data passed in from the controller. I am able to iterate the collection in my view but I am unable to access the relationship data.
There are 2 tables:
stocks (default model)
stock_datas (has a foreign key stock_id which is already setup)
Controller:
public function getstock() {
return view('vehicles.getstock', ['stock' => \App\Stock::all()]);
}
Model (App\Stock) and then (App\StockData)
// From stock model:
public function stockdata() {
return $this->hasOne('App\StockData');
}
// Stock Data model:
public function stock() {
return $this->belongsTo('App\Stock');
}
View (loop):
#foreach ($stock as $k => $v)
{{ print_r($v->stockdata()->get())->year }}
#endforeach
When I try the query below, I get a
Undefined property: Illuminate\Database\Eloquent\Collection::$year (View: F:\websites\tempsite\resources\views\vehicles\getstock.blade.php)
However, year is a column in the stock_datas table.
I am also able to print_r data from the \App\StockData() table so the reference to the table is correct as doing print_r(\App\StockData::all()) from the controller does return all the rows as expected.
What am I doing wrong?
Since it's one to one relation, you should do it like this:
#foreach ($stock as $v)
{{ $v->stockdata->year }}
#endforeach
First one You have to change {{ print_r($v->stockdata()->get())->year }} this line, remove print_r. Next one in foreach loop you can do something like this
#foreach($stock as $one)
{{ $one->stockadata()->first()->year }}
#endforeach
For better solution you should check if isset $one->stockadata()->first()
and after that call ->year. Finally code should be like this
#foreach($stock as $one)
{{ isset($one->stockadata()->first()) : $one->stockadata()->first()->year : 'Default' }}
#endforeach
When calling get() method on any relationship You will always receive collection, no matter what relationship You have.
There are at least two (2) ways to solve Your problem:
1. $v->stockdata->year
2. $v->stockdata()->first()->year
I would suggest You to use first one, because Your stockdata has 1:1 relationship.
Good luck!
For example:
Stock.php model
class Stock extends Model
{
protected $primaryKey = 'id';
function stockdata() {
return $this->hasOne('App\StockDatas', 'id', 'stock_id');
}
public function getStock(){
return Stock::with('stockdata')->get();
}
}
In contriller
public function getstock(Stock $stock) {
return view('vehicles.getstock', ['stock' => $stock->getStock]);
}
view
#foreach ($stock as $k => $v)
{{ $v->stockdata->year }}
#endforeach

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.

Resources