Model relations not working when using queryBuilder methods in Laravel - php

How can I use Laravel Relations while using Query Builders ?
$Cars = User::find(1)->car; // works well and returns all cars
$User = User::where('username' , 'John')->get();
$Cars = $User->car; // doesn't work.
Any help.
thanks
Solved
$User = User::where('username' , 'John')->get();
Should Be
$User = User::where('username' , 'John')->first(); // to get an object instead of array

The ::find() method will return an instance of your model, which allows you to access relations and such that are setup on the model.
The ->get() method will return an Illuminate\Database\Eloquent\Collection of results, even if there is only 1 row selected from the database.
Using the collection you can then loop through the results
$collection->each(function($model)
{
// You can now access $model->cars
});
Alternativly you may use the ->first(), ->last() and ::find() methods to return a single instance of your model which allows you to directly access relations.
$model = Model::where('foo', 'bar')->first(); // Returns first row from the database
$model->cars // Is now accessable

Assuming you already have your Cars class all you have to do is to add method to your User class.
//add this method to your User class
public function cars()
{
//since you'll be using many to many
//you might use `user_cars` as pivotal table
return $this->belongsToMany('Cars', 'user_cars', 'cars', 'cars');
}
You may call it using:
User::find(1)->cars()->get();

Related

Copying Data from table to another table and applying one to many relationship

This is my Report Model
protected $fillable = [
'site_url',
'reciepients',
'monthly_email_date'
];
public function site()
{
return $this->belongsTo('App\Site');
}
This is my Site Model
public function report()
{
return $this->hasMany('App\Report');
}
This is my ReportController
public function showSpecificSite($site_name)
{
$records = DB::table('reports')
->select('email_date','url','recipient')
->whereHas('sites', function($query){
$query->where('site_name',$site_name);
})
->get();
return view('newsite')->with('records',$records)
->with('site_name',$site_name);
}
My Controller is not yet working as well.
The thing is I would like to copy all the three files from sites table to reports table.
Is it possible in insertInto ?
My code on ReportController shows you that I'm selecting data from reports table but I am the one who puts data to reports table to see the output but it is not yet working because of the it cant reach out the value of site_name even though I already put a relationship between the two tables.
You're not actually using Eloquent in your controller you're just using the Query Builder (DB). This will mean that you don't have access to anything from your Eloquent models.
Try:
$records = \App\Report::whereHas('site', function($query) use($site_name) {
$query->where('site_name', $site_name);
})->get(['id', 'email_date', 'url', 'recipient']);
I've added id to the list of columns as I'm pretty sure you'll need that to use whereHas.
NB to use a variable from the parent scope inside a closure you need to pass it in using use().

Failure to extract data from a relationship with laravel

I am trying to make a one-to-many relationship, but I get the following error
Undefined property: stdClass::$client (View:
C:\wamp\www\intranet\resources\views\users\list.blade.php)
The problem is that I am working with an existing database that in the tables does not have id fields, and the foreign keys would also be the typical ones like client_id
My model Client.php
class Client extends Model
{
protected $connection = 'dpnmwin';
protected $table = 'nmundfunc';
public function employee(){
return $this->hasMany('App\Employee');
}
}
My model Employee.php
class Employee extends Model
{
protected $connection = 'dpnmwin';
protected $table = 'nmtrabajador';
public function client(){
return $this->belongsTo('App\Client', 'COD_UND');
}
}
In nmtrabajador COD_UND field would be the foreign key that relates to nmundfunc.
And I try to get the data out like this: {{$user->client->CEN_DESCRI}}.
but it does not throw me the error, how can I solve it?
My Controller where I send in sight
public function index(){
$users = DB::connection('dpnmwin')->table('nmtrabajador')->where('CONDICION', '=', 'A')->get();
return view('users.list',array(
'users' => $users
));
}
You have to call basis on relations.
This code will return you data.
If you have id then you can find by id like below
$employee=Employee::find(1);
Or if you want to fetch all data then you can call all method.
Employee::all();
And then you can just get it by relation as you define in models.
$client=$employee->client->CEN_DESCRI;
Retrieving data from the instance is based on the methods which we have use.
Here in this answer, you can get that
Property [title] does not exist on this collection instance
I hope it will work.
If table doesn't have 'id' as primary key you should specify what the primary key is inside your model:
protected $primaryKey = 'your_primary_key';
Relation looks good, after that you must make sure $user is a defined instance of Employee, because your error probably means that your instance wasn't even defined, so for example if you are using list.blade.php, you need to change the return of your controller and indicate that you want to pass data to your view, for example you could do it like this:
return view('users.list', compact('user'));
Where user is an instance of Employee saved on '$user'
Update
First you should check your user is retrieved properly, you can check it by placing a dd($user)
And when you return a view you can pass information to it, a cleaner way of doing what you are trying to do is what I wrote earlier so you would end up having something like this:
public function index()
{
$users = DB::table('nmtrabajador')
->where('CONDICION', '=', 'A')
->get();
// dd($user) for debugging you are retrieving the user properly
return view('users.list', compact($users));
}

Pass variable to laravel method from within the same model

I am working on some multi tenancy updates to a Laravel app but hitting an issue when trying to pass a specific team ID into a method on a model from within another method.
Example:
In Controller:
$waitTime = $booking->estimatedWaitTime($teamId);
In Booking model:
public function queueLength()
{
$booking = $this->todaysBookings;
foreach ($bookings as $booking) {
// Calculate the length of all bookings
}
}
public function todaysBookings()
{
return $this->hasMany('App\UserBooking')->whereHas('booking', function ($q) {
$q->where('team_id', 2);
});
}
This correctly returns the bookings and allows me to loop through them in the queueLength method. However, I want to be able to pass the team_id into the todaysBooking method.
When instead calling todaysBookings as a method:
$booking = $this->todaysBookings();
It doesn't return anything for me to loop through.
Any ideas how to achieve what I want to do here?
You can pass the id as parameter and then get the results :
public function todaysBookings($team_id)
{
return $this->hasMany('App\UserBooking')->whereHas('booking', function ($q) use($team_id) {
$q->where('team_id', $team_id);
});
}
In the call you can do as follow :
$some_teame_id = 2;
$booking = $this->todaysBookings($some_teame_id)->get();
Why ?
Because the relationships in laravel serve as powerful query builders (documentation) :
Eloquent relationships are defined as methods on your Eloquent model
classes. Since, like Eloquent models themselves, relationships also
serve as powerful query builders, defining relationships as methods
provides powerful method chaining and querying capabilities.
Relationship Methods Vs. Dynamic Properties :
The call of the relationship as Methods is needed when you want to add some more conditions and filters like this :
$booking->todaysBookings()->where('active', 1)->get(); //just an example :)
And if you do not need to add additional constraints to an Eloquent relationship query, you may simply access the relationship as if it were a property, Laravel will add the get() for you :)
$booking->todaysBookings

Custom model method to get a relation in Laravel

I try to define a custom Model method in Laravel. I have a n:m relation between Subscription and Notification over SubscriptionNotification.
I already defined the default relations:
public function subscription_notifications() {
return $this->hasMany('App\SubscriptionNotification');
}
public function notifications() {
return $this->belongsToMany('App\Notification', 'subscription_notifications');
}
Now I want to define a method, which returns a collection of notifications. I collect the IDs of the notifications I want in an array and write the following method:
public function notifications_due() {
// Collect $notification_ids
return $this->belongsToMany('App\Notification', 'subscription_notifications')->whereIn('notifications.id', $notification_ids)->get();
}
But when I want to use the mothod by $subscription->notifications_due, I get the following error:
[LogicException]
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
I'm new to Laravel (I come from Rails). I don't know if this is in Laravel even possible. Maybe someone can help me. Thanks!
Remove the ->get() part in the method notifications_due. get() will return a Collection, but when calling the method as a property (or magic method), Laravel expects the method to return an instance of Relation. Laravel will then execute the query and transform it to a Collection automatically.
Also, you can use your already defined notifications() method:
public function notifications_due() {
// Collect $notification_ids
return $this->notifications()->whereIn('id', $notification_ids);
}
Remove the get call from your relationship method, for example:
public function notifications_due() {
return $this->belongsToMany(
'App\Notification',
'subscription_notifications
')->whereIn('notifications.id', $notification_ids);
}
Use it just same:
// It'll return a collection
$dues = $subscription->notifications_due;
To get all the ids from the collection you may try this:
$ids = $dues->pluck('id');
Also, you may add more constraints if you want if you use it like:the
$dues = $subscription->notifications_due()->where('some', 'thing')->get();
Or paginate:
$dues = $subscription->notifications_due()->where('some', 'thing')->paginate(10);

Access to many-to-many relation in array format, symfony2

in symfony we can access many-to-many relations with getter functions which return objects of ArrayCollection type.
for example for getting Alex's students we can call $alex->getStudens(), then i have access to ale's studens object.
now my question is how i can access alex's students id's in array, for example by calling $alex->getStudentsIds() it returns {1,5,7,12,..} , which are his students's ids.
precisely how you wrote it, you add another function in the entity
public function getStudentsIds()
{
$students = $this->students;
$studentIds = [];
foreach($students as $student)
{
$studentIds[] = $student->getId();
}
return $studentIds;
}
Ideal solution would be to add such a method to a repository and have it query only for student ids for given object but this is the simpliest solution possible.

Categories