Eloquent get value Many to Many Relationship - php

This is my Vote model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vote extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
public function options(){
return $this->hasMany('App\Option');
}
}
this is my Option model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Option extends Model
{
public function vote(){
return $this->belongsTo('App\Vote');
}
public function users(){
return $this->belongsToMany('App\User');
}
}
The case is i want to get the users data from many to many relationship in Option model, but started from Vote model. So i get the options data in the Vote model first, then i get the users data in Option model (many to many)

Laravel has no native support for a direct relationship.
I've created a package for cases like this: https://github.com/staudenmeir/eloquent-has-many-deep
class Vote extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function users()
{
return $this->hasManyDeep(User::class, [Option::class, 'option_user']);
}
}

Related

Polymorphic relation not inserting model type in database

In my Laravel application, I have different models that can be reported so I am using a polymorphic relationship. Posts, Threads and solutions are reportable and can be MorphedToMany. When I try to create a new report in my controller I get General error: 1364 Field 'reportable_id' doesn't have a default value (SQL: insert into `reports` (`channel`, `updated_at`, `created_at`) values ({"id":18,"created_at":"2020-08-20T09:37:06.000000Z","updated_at":"2020-08-20T09:37:06.000000Z","name":"marketing"}, 2020-08-21 09:13:45, 2020-08-21 09:13:45)) as an error
I followed the documentation the tutorial but I can't spot the error
here is my code with the post class as an example
post
use Illuminate\Database\Eloquent\Model;
use Cog\Contracts\Love\Reactable\Models\Reactable as ReactableContract;
use Cog\Laravel\Love\Reactable\Models\Traits\Reactable;
class Post extends Model implements ReactableContract
{
/**
* #var mixed
*/
use Reactable;
protected $fillable=['title','body'];
protected $guarded=[];
public function user(){
return $this->belongsTo('App\User');
}
public function tags(){
return $this->belongsToMany('App\Tag');
}
public function channel(){
return $this->belongsTo('App\Channel');
}
public function comments(){
return $this->hasMany('App\Comment');
}
public function reports(){
return $this->morphToMany('App\Report','reportable');
}
}
report
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
protected $guarded=[];
public function reportable(){
return $this->morphTo();
}
}
reportController
use App\Comment;
use App\Post;
use App\Report;
use App\Solution;
use App\Thread;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ReportController extends Controller
{
public function create(){
switch (\request('table')){
case 'posts':
$model=Post::find(\request('model'));
break;
case 'threads':
$model=Thread::find(\request('model'));
break;
case 'solutions':
$model=Solution::find(\request('model'));
//for now we are not implementing comments since is gonna be more complicated
}
//save model into database
$report=new Report();
$report->channel=$model->channel->name;
$model->reports()->create(['channel'=>$model->channel]);
//notify user
//redirect to channel
}
}
Solved I used MorphToMany instead of MorphMany

How to get all data from two related tables in Laravel [one to many]

I am pretty new in Laravel and need write a simple backend API.
I am doing smething wrong and I dont know what, because I get some of data from Suppliers table and empty array payments:[ ].
I am trying to get all data from two related tables - PAYMENTS and SUPPLIERS.
It`s a one to many relation SUPPLIERS_ID in PAYMENTS table is connected with ID in SUPPLIERS. Here I give You a graphic representation:
Here`s my code:
Suppliers.php model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Suppliers extends Model
{
public function payments()
{
return $this->hasMany('App\Payments');
}
}
Payments.php model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Payments extends Model
{
public function suppliers()
{
return $this->hasOne('App\Suppliers');
}
}
PaymentsController.php
use App\Payments;
use App\Suppliers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class PaymentsController extends Controller
{
public function index()
{
$payments = Suppliers::with('payments')->get();
return response($payments, Response::HTTP_OK);
}
}
And i get the following answear:
[{"id":1,"name":"Ekonaft","adress":"33-100 Tarnow ","email":"ekonaft#gmail.com","payments":[]},
{"id":2,"name":"Orlen","adress":"Ares testowy","email":"email#email.pl","payments":[]}]
What I`m doing wrong that I get te empty array payments:[ ] on the end of each object?
Try the inverse relationship on payments
belongsTo = has a foreign key to another table
Quoting an example
Should i use belongsTo or hasOne in Laravel?
This is how you can access suppliers from Payments
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Payments extends Model
{
public function suppliers()
{
return $this->belongsTo('App\Suppliers');
}
}
This is payments from suppliers
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Suppliers extends Model
{
public function payments()
{
return $this->hasMany('App\Payments','suppliers_ID','id');
}
}
Also, make sure the id's are visible on the output (if id's are hidden, laravel can't work with the relationship). You can also specify the keys on the relationship if you want to use hasOne
Edit: add the keys names within the relation, your fk naming is in capslock
Change you relations like bel
Suppliers.php model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Suppliers extends Model
{
public function payments()
{
return $this->hasMany(App\Payments::class, 'suppliers_ID', 'id');
}
}
Payments.php model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Payments extends Model
{
public function suppliers()
{
return $this->belongsTo(App\Suppliers::class, 'suppliers_ID', 'id');
}
}
then try again..... :)
You are getting empty array of payments:[] due to miss-matching table relationship key name.
Please, make few changes in both relational function.
public function payments()
{
//return $this->hasMany('App\Model', 'foreign_key', 'local_key');
return $this->hasMany('App\Payments', 'suppliers_id');
}
public function suppliers()
{
//return $this->belongsTo('App\Model', 'foreign_key', 'other_key');
return $this->belongsTo('App\Suppliers', 'suppliers_id');
}
You can learn more about eloquent relationship directly from Laravel documentation for better understanding. https://laravel.com/docs/5.7/eloquent-relationships#one-to-many
Let me know if you still getting same error.

Laravel Eloquent: hasManyThrough Many to Many relationship

I have the following classes (simplified here) in my Laravel 5.7 model:
VEHICLE.PHP
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vehicle extends Model
{
public function journeys()
{
return $this->hasMany('App\Journey');
}
}
JOURNEY PHP
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Journey extends Model
{
public function vehicle()
{
return $this->belongsTo('App\Vehicle');
}
public function users()
{
return $this->belongsToMany('App\User');
}
}
USER.PHP
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function journeys()
{
return $this->belongsToMany('App\Journey');
}
}
I have an intermediate table (journey_user) between users and journeys (see schema attached).
I can easily get all journeys made by a particular user. But how can I get all vehicles used by a particular user? The standard hasManyThrough method does not appear to work because of the Many to Many relationship between users and journeys.
Thanks for your help!
I haven't tested this out. However, it should be possible to get all vehicles by looping through all the user's journeys, creating an array of vehicles and return this as a collection.
This can be added to your User.php model controller:
/**
* Get all vehicles which user has used
*
*/
public function vehicles()
{
$vehicles = [];
$this->journeys()
->each(function ($journey, $key) use (&$vehicles) {
$vehicles[] = $journey->vehicle;
});
return collect($vehicles);
}
Here, we create an empty array. Then we loop through all the journeys of the users (passing the $vehicles array as a reference to update it).
We use the each() collection method to loop through each journey. We create a new entry to the $vehicles array, adding the vehicle.
Finally, we return all vehicles as a collection.
We can use this in our application like so:
User::find($id)->vehicles();
Note: You could return this as an accessor attribute by changing the function name to setVehiclesAttribute(). This will allow you to access the vehicle field like User::find($id)->vehicle.

How to get first row in Laravel relationship

How can i create a method in my model below that consist of first value of pages?
I want my cover method to get he first instance of pages.
Here's my model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
protected $guarded = [];
public function pages()
{
return $this->hasMany('\App\Page');
}
public function cover()
{
//first page of pages here
}
}
Use the first() method on the relationship
public function cover()
{
return $this->pages()->first();
}

Simple way to compare manytomany relationships? Laravel 5.3

I have a set of relationships that looks like this:
The users and agencies have a lot of data stored in them, in addition to the pivot tables you see there.
What I'd like to do is find the agencies or users that match the preferences of the currently logged in individual, whether they are an agency or user.
It's a straight comparison, so nothing fancy. But I honestly have no idea how to write the eloquent query to account for the pivot tables. Can someone point me in the right direction?
I'm looking at something like this, which is understandably failing:
$loggedinagency = Auth::user()->id;
$match_user_agency = User::with('work_prefs')
->where('work_prefs', 'like',
Agency::find($loggedinagency)->work_prefs)
->get();
Edit: The relationships are declared like so:
User:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
protected $table = 'users';
public function work_prefs() {
return $this->belongsToMany('App\Work_Prefs', 'preference_user', 'user_id', 'preference_id');
}
}
Agency:
<?php
namespace App;
class Agency extends Authenticatable
{
use Notifiable;
protected $table='agencies';
public function work_prefs() {
return $this->belongsToMany('App\Work_Prefs', 'agency_preference', 'agency_id', 'preference_id');
}
}
Work Preferences:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Work_Prefs extends Model
{
protected $table = 'work_prefs';
public function user() {
return $this->belongsToMany('App\User', 'preference_user', 'preference_id', 'user_id');
}
public function agency() {
return $this->belongsToMany('App\Agency', 'agency_preference', 'preference_id', 'agency_id');
}
}

Categories