Retrieving relevant record from a relationship - laravel

I am allowing user to search by type which is passed into a function:
public function typeSearch($type)
{
$events = Event::where('type', $type)
->with('entities')
->get();
return view('events.searchResultEvents', compact('events'));
}
Which works nearly as it's supposed to do, it does retrieve the entities but not the right entities for example:
Event id = 25, entity_id = 2 it retrieves: Entities id = 25 while it should be 2.
How can I change this so it retrieves the right record?
Example::
Looking at the image, Event is = 25 and entity_id = 1. entity_id is a foreign key which is linked to id on 'entities' table
From Relations we have 'entities' with id = 25, while it should be 1 as entity_id = 1
Event model::
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Event extends Model
{
protected $table = 'events';
public $timestamps = true;
use Searchable;
public function entities()
{
return $this->belongsTo('App\Entity', 'id');
}
public function users()
{
return $this->belongsTo('App\User', 'id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'id');
}
}

I think there's problem in your relations method.
public function entities()
{
return $this->belongsTo('App\Entity', 'id'); // Ithink you need to change it
}
Change that 'id' in your second parameter to 'entity_id'
public function entities()
{
return $this->belongsTo('App\Entity', 'entity_id');
}
The second parameter is used like this, I don't know how to explain it in technical but here's an example:
$event = Event::find(1);
//this will return the events with id=1 and that data have entity_id=2
$entities = $event->entities;
//If you set the second parameter in your Event model to 'id',
//this $entities variable contain the data from entities table with id=1, because your $event id=1
//But if you set the second parameter to 'entity_id'
//this $entities variable contain the data from entities with the id=2, because your $event entity_id=2

Related

Laravel query builder with the User and Auth

How to List all rows from a table (agendas) in my DB where records are saved by the connected user.I'm using default Auth from Laravel.
public function index ($id = null)
{
$agendas = Agenda::where('id', Auth::user()->id)->get();
$users = User::all();
return view('admin.agendas.index', compact('agendas','users','id'));
}
My controller here.
Need help
Assuming
agendas table (containing records for Agenda model) has a column user_id which references the id column on users table
User hasMany Agenda
Agenda belongTo User
class User extends Model
{
public function agendas()
{
return $this->hasMany(Agenda::class);
}
//... rest of class code
}
class Agenda extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
//... rest of class code
}
public function index($id = null)
{
$user = User::with('agendas')->findOrFail(auth()->id());
return view('admin.agendas.index', [
'user' => $user,
'agendas' => $user->agendas,
'id' => $id
]);
}
Your User model should have a relationship:
public function agendas()
{
return $this->hasMany(Agenda::class);
}
In your controller, you could then simplify the use as such:
public function index (Request $request, $id = null)
{
$agendas = $request->user()->agendas;
$users = User::all();
return view('admin.agendas.index', compact('agendas','users','id'));
}
if you wanna get data related to another data , you have to join those tables together by a field. in this case i guess you have a column in Agenda table named 'user_id'.
you have two way :
join tables in your Model.
search in Agenda table in your controller
if you want to use joining your tables from model :
// in App\User.php
...
class User ...{
...
public function Agenda(){
return $this->hasMany(Agenda::class);
}
...
}
...
then you can access to all of "Agenda" from everywhere like this :
Auth()->user()->agenda
if you want to search in table from your controller you can do :
Agenda::where('id', Auth::user()->id)
you can read more about eloquent-relationships in : https://laravel.com/docs/8.x/eloquent-relationships

How do i delete all rows based on a single column in one to many relationship in laravel eloquent?

When deleting a particular movie , i want to delete all showtime related to it. I have 3 tables related to this query.
Showtime (which has m-m relation with times table (pivot table showtime_time)
Times
Movies
What i tried is:
MovieController:
public function destroy($id)
{
$movie = Movie::findOrFail($id);
if (ShowTime::where('movie_id', '=', $id)->exists()) {
$showtimes = ShowTime::whereIn('movie_id', '=', $id)->get();
foreach ($showtimes as $showtime) {
$showtime->times()->detach();
$showtime->delete();
$movie->delete();
}
return back();
} else {
$movie->delete();
}
return redirect()->route('movies.index');
}
Which gave me this error.
Argument 1 passed to
Illuminate\Database\Query\Builder::cleanBindings() must be of the type
array, string given, called in
C:\Users\lenovo\cinetime_nepal_backend\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php
on line 907
Model class
<?php
namespace Modules\Movie\Entities;
use Illuminate\Database\Eloquent\Model;
class Movie extends Model
{
protected $guarded = ['id']; //fillable
protected $hidden = ['created_at', 'updated_at'];
public function showTimes()
{
return $this->hasMany(ShowTime::class, 'movie_id');
}
}
This is how i am deleting showtime in showtimecontroller
ShowtimeController
public function destroy($id)
{
$showtime = ShowTime::findOrFail($id);
$showtime->times()->detach();
$showtime->delete();
return back();
}
I am new to laravel, i searched and tried many codes answered in this site but could not help myself.
Help Please
If you're using MySQL you can add 'ON DELETE CASCADE' to your foreign key. This will automatically delete any records that reference the parent when the parent is deleted. just put it to your showtime migration
$table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
Or, if you don't want that approach, then you can overwrite your delete method in your movie model. Put this code in your movie model.
public function delete() {
$this->showTimes()->times()->delete();
$this->showTimes()->delete();
parent::delete();
}
Then in your controller you just delete your movie and it's all fine.
public function destroy($id)
{
$movie = Movie::findOrFail($id);
$movie->delete();
return redirect()->route('movies.index');
}

Trying to display eloquent data base from ID's

Hi I am trying to create a record base from ID of an order transaction.
I have here the ORDERS, CAMPANIES and CURRENCIES models.
Now I want the ORDER to get the ID from a URL Parameter, and then the companies should grab the company_id from Orders same with currency, I want to grab the currency_id from orders.
Here's what I came up so far:
public function create($order_id)
{
$order = Orders::find($order_id)->where('id', '=', $order_id)->get();
$company = Companies::where('id', '=', $order['company_id'])->get();
$currency = Currencies::where('id', '=', $order['company_id'])->get();
$banks = Banks::all('name','acronym','id')->get();
return view('orderPayments.create', compact('order'))
->with('company', $company)
->with('currency', $currency)
->with('banks', $banks);
}
currencies model
public function orderPayments()
{
return $this->hasMany('App\Orderpayments', 'id','currency_id');
}
Companies Model
public function orderPayments()
{
return $this->hasMany('App\Orderpayments', 'id','company_id');
}
Order Payments Model
public function company()
{
return $this->hasOne('App\Companies', 'id','company_id');
}
public function currency()
{
return $this->hasOne('App\Currencies', 'id', 'currency_id');
}
public function bank()
{
return $this->hasOne('App\Bank', 'id', 'currency_id');
}
How can I achieve it? thank you so much in advance!
UPDATE
I just applied #sandy's answer. I checked if the $order has a content so I echod the $order by doing this, {{ $order }} The return value is ok.
but when I calling the other attributes like $order->grandtotal, or $order->companies->comp_name the error is
If your relationship between your models is a One To Many relationship you should use belongsTo in your relations like this:
OrderPayment Model
public function company()
{
return $this->belongsTo('App\Companies','company_id');
}
public function currency()
{
return $this->belongsTo('App\Currencies','currency_id');
}
public function bank()
{
return $this->belongsTo('App\Bank', 'currency_id');
}
Also, the second parameter on the function should be your foreign key.
Answering your question:
If you want to access the relations of a given Order you could do this:
$order = Order::find($order_id);
$order->company; // this will return the company
$order->currency; // this will return the currency
If you want to display in your view:
{{$order->company->anyCompanyAttribute}}
Note:
You should name your models in SINGULAR like Currency, Company. Not in plural.
try like this
$order = Orders::with(['company','currency'])->where('id', '=', $order_id)->get();

Laravel scout check if relation is not empty?

namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Event extends Model
{
protected $table = 'events';
public $timestamps = true;
use Searchable;
use SoftDeletes;
protected $dates = ['deleted_at'];
public function entities()
{
return $this->belongsTo('App\Entity', 'entity_id');
}
public function users()
{
return $this->belongsTo('App\User', 'id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'id');
}
public function toSearchableArray()
{
$data = $this->toArray();
$data['entities'] = $this->entities->toArray();
return $data;
}
}
This is my model for Event, as you can see I am using toSearchableArray which is Laravel scout function to import 'relations' to algolia. However the problem is that sometimes it is empty. So for example
event id 1 has entity_id 1
but in another example
event id 2 has entity_id = null
How can I modify this function to check if the entities() relation is not empty before putting it into array?
if i understand u correctly this should help. if the relationship does not exist return an empty array and scout won't update the index
public function toSearchableArray()
{
if(is_null($this->entities)){
return [];
}
$this->entities
return $this->toArray();
}
please update foreign_key in relation as this
user_id as foreign_key instead of id
event_id as foreign_key instead of id
public function users()
{
return $this->belongsTo('App\User', 'user_id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'event_id');
}
I think if load the relation before the toArray().
public function toSearchableArray()
{
$this->entities;
return $this->toArray();
}

Laravel 5.3 belongsToMany return null, pivot data

I have a next models:
class Product extends Model{
protected $table = 'products';
public function payments()
{
return $this->belongsToMany('App\Payment', 'payment_product', 'product_id', 'payment_id')
}
}
class Payment extends Model{
protected $table = 'payments';
public function products(){
return $this->belongsToMany('App\Product');
}
}
Pivot table: payment_product(id, product_id, payment_id)
Eloquent
public function details($id){
$product = Product::with('payments')->find($id);
dd($product->payments); // return null
return view('products.details', ['product' => $product]);
}
I need to bring in a foreach, but $product->payments is null. Why is that ?
All the tables are not empty.
UPD
Sub query $this->belongsToMany('App\Payment', 'payment_product', 'product_id', 'payment_id');
Results:
try:
public function payments()
{
return $this->belongsToMany('App\Payment', 'payment_product', 'payment_id', 'product_id')
}
I think you have your FK in the wrong order.
In fact, I don't think you need to specify anything more than:
public function payments()
{
return $this->belongsToMany('App\Payment')
}
Looks like you are joining two tables based on unrelated fields.
When you do
return $this->belongsToMany('App\Payment', 'payment_product', 'product_id', 'payment_id')
your table products gets inner joined with payment_product on
products.product_id = payment_product.payment_id.
But I think these two columns are not the related keys. Instead, in your payment_product, join with the product_id in this table with products.product_id.
That might work.
Rename payments to payments_method:
public function payments_method(){
return $this->belongsToMany('App\Payment'); //or ('App\Payment', 'payment_product', 'payment_id', 'product_id')
}
$product = Product::find($id);
$product->payments_method; //this is work
This is magic:)

Resources