How to display a complex relationship field for Laravel Backpack? - php

I have a relationship
Candidate -> Vacancy -> User
Candidate:
class Candidate extends Model
{
public function vacancy()
{
return $this->belongsToMany(
Vacancy::class,
'vacancy_has_candidate',
'candidate_id',
'vacancy_id'
);
}
}
Vacancy:
class Vacancy extends Model
{
public function candidate()
{
return $this->belongsToMany(
Candidate::class,
'vacancy_has_candidate',
'vacancy_id',
'candidate_id'
);
}
public function manager() {
return $this->hasMany(User::class, 'manager_id');
}
}
User:
class User extends Authenticatable
{
public function vacancy()
{
return $this->belongsTo(Vacancy::class, 'manager_id');
}
}
I want to display in СRUD candidates the field of the relationship in which I call the manager method with the output of the field from the User model.
for example
class CandidateCrudController extends CrudController
{
....
public function setupCreateOperation()
{
$this->crud->addFields([
[
'name' => 'vacancy',
'type' => 'relationship',
'label' => 'Vacancy',
'model' => Vacancy::class,
'entity' => 'manager', <- this method in Vacancy model
'attribute' => 'title', <- this column name in User
'ajax' => true,
]
]);
...
I get an error
"Looks like field vacancy is not properly defined. The manager() relationship doesn't seem to exist on the App\Models\Candidate model"
I can’t understand why the backpack is looking for a manager method in Candidates, although in the model I indicated a Vacancy in which this relationship method exists. And how to do it right?

KorDEM.
You will not be able to achieve that as per Backpack Documentation:
entity is the method that defines the relationship on the current model, in your case App\Models\Candidate is the CrudController model. So entity there should be the vacancy relation.
If you are using Backpack\PRO paid addon you should be able to list the vacancies with the desired information by using something like:
$this->crud->addField([
'name' => 'vacancy',
'subfields' => [
['name' => 'manager']
]
]);
If you need aditional pivot fields you need to provide ->withPivot in the relation.
Check BelongsToMany documentation on Backpack website

Related

Backpack for laravel -> I can't get + Add Inline Create

I want to use the Inline Create functionality of Backpack for Laravel but the button "Add +" doesn't shows up.
I have a 1 to n relationship
The primary model is Inscription and the secondary is InscriptionProduct
This is my code:
Models\Inscription
...
class Inscription extends Model
{
public function product() {
return $this->hasMany('App\Models\InscriptionProduct');
}
...
Models\InscriptionProduct
...
class InscriptionProduct extends Model
{
public function inscription()
{
return $this->belongsTo(Inscription::class);
}
...
Http\Controllers\Admin\InscriptionProductCrudController
...
class InscriptionProductCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
...
Http\Controllers\Admin\InscriptionCrudController
...
class InscriptionCrudController extends CrudController
{
protected function setupCreateOperation()
{
...
$this->crud->addField([
'type' => "relationship",
'name' => 'product',
'ajax' => true,
'inline_create' => true,
// 'data_source' => backpack_url('/admin/inscription-product/inline/create'),
// 'data_source' => backpack_url('inscription/fetch/inscription-product'),
// 'inline_create' => [ 'entity' => 'inscriptionproduct' ]
// These 3 commented lines are alternatives also tried with no results
]);
...
The Relationship is well constructed because I can see the Products I have created via the CRUD of InscriptionProduct
What am I missing?
I solve it to, in your main CrudController, you should call the InLineCreate just below CreateOperation.
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation { store as traitStore; }
Also in my secondary CrudController I had to create a fetch function, something I did
protected function fetchFeatures()
{
return $this->fetch([
'model' => \App\Models\Features::class, // required
'searchable_attributes' => ['name', 'slug'],
'query' => function($model) {
return $model;
} // to filter the results that are returned
]);
return $this->traitFetch();
}

Laravel error: Property [name] does not exist on this collection instance

I'm trying to get a partner for each order using Laravel resource collections. But this throws up an error:
Property [name] does not exist on this collection instance
I get partners this way
Order_product.php
//...
class Order_product extends Model
{
protected $fillable = ['order_id', 'product_id', 'quantity', 'price'];
public function partner()
{
return $this->hasManyThrough(
'App\Partner', 'App\Order',
'partner_id', 'id', 'order_id');
//orders partners order_products
}
//...
Resources\Order_product.php
class Order_product extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'order_id' => $this->order_id,
'product_id' => $this->product_id,
'quantity' => $this->quantity,
'price' => $this->price,
'status' => $this->order->status,
'product_name' => $this->prod->name,
//return error
'partner_name' => $this->partner->name,
];
/*
//this method return:
//Invalid argument supplied for foreach() {"exception":"[object]...
$partners = [];
foreach($this->collection as $partner) {
array_push($partners, [
// 'partner_name' => $this->partner->name
]);
}
return $partners;
*/
}
}
Each order has one partner name. In the future, I will group them, but now I just need to output the partner_name
is relations when you use hasMany or hasManyThrough it returns you a collection, so you should use it in foreach or use with index
return [
'product_name' => $this->prod->first()->name, //first array in collection using first()
];
OR
return [
'product_name' => $this->prod[0]->name, //first array in collection using index
];
or you can write this code in foreach!
As you are using hasManyThrough or hasMany laravel relationship returns Illuminate\Database\Eloquent\Collection Instance.
If you want to get name you have to have one Model instance.
Solution 1: $this->parthner->first()->name
Solution 2: See this hasOneThough
public function partner(){
return $this->hasOneThrough(
'App\Partner', 'App\Order',
'partner_id', 'id', 'order_id');
}
Depens on your app logic
Hope this helps you

how to use laravel eloquent to get and display data from other tables

I was using these codes in my controller to get all the data from my 2 tables and it works fine
$All = Customers::with('order')->paginate(10);
return response()->json([
'code' => 0,
'success' => true,
'data' => $All
], 200);
Here is how I define the relationship between these 2 tables
class Customers extends Model
{
public function order()
{
return $this->hasMany(Orders::class, 'customer_id', 'id');
}
}
class Orders extends Model
{
public function customers()
{
return $this->belongsTo(Customers::class, 'customer_id', 'id');
}
}
Now my desire output is to hide the order id, order timestamps and change the customer_id to customer's name (the customer's name is not in my orders db table).
I'm using 'data' => DataResource::collection($All) in my controller and this is my DataResource
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'order' => $this->order
];
}
and of course the output is same with the image above.
My database structure:
orders table:
customer table:
Can anyone help me with that?
The answer is simple and basically a copy of the official documentation. You simply need to wrap your orders in an OrderResource as well.
// DataResource
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'order' => OrderResource::collection($this->order)
];
}
// OrderResource
public function toArray($request)
{
return [
'items' => $this->items,
'quantity' => $this->quantity
];
}
I don't really understand why you would want to include the customer_name in your orders when it is already present on the customers object one hierarchy above. But if you really want to add it, you should be able to do so with: 'customer_name' => $this->customers->name.
As a side note: you really should be more consistent with your naming. Why is the resource called DataResource when it is about Customers? Why is your model called Customers in plural form rather than Customer in singular, which is the convention (and more logical if you consider that one model represents one customer). Why is your belongsTo relation called customers() in plural when it returns one customer, while your hasMany relation is called order whereas it returns one or more orders?

Yii multiple relations between different models in different modules

How would i add a 3rd relation to my relations() function to join the CommentsPosts model with the store model. Where CommentsPosts.store_id = Store.id and CommentsPosts.store_zip = Store.zip?
in my comment.php
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, $this->module->userModelClass, 'userId'),
'posts' => array(self::HAS_MANY, "CommentsPosts", array("commentId" => "id")),
'store'=>'',
);
}
CommentsPost.php is in modules/comments/model and Store.php is in modules/store/model
FYI, i'm using Yii 1.1.15
I'm not sure about your relations but try something like bellow
In Comment post Model add the relation
public function relations()
{
return array(
'store' => array(self::HAS_MANY, "Store", array("store_id" => "id")),
);
}
When retrieving
$enity->post // give all post
$enity->post[i]->store // gives the each post data of store

codeigniter doctrine many to many relationships

I have three tables.
User
id
Group
id
UserGroup
user_id
article_id
date_joined
Now I have three separate models to set up the relationship.
// User Model
<?php
class User extends Doctrine_Record
{
// define table columns in this function
public function setTableDefinition() {
}
// setup some options
public function setUp() {
$this->hasMany('Group as Groupss', array(
'local' => 'user_id',
'foreign' => 'group_id',
'refClass' => 'UserGroup'
));
// causes 'created_at' and 'updated_at' fields to be updated automatically
$this->actAs('Timestampable');
}
}
// Group Model
<?php
class Group extends Doctrine_Record
{
// define table columns in this function
public function setTableDefinition() {
}
$this->hasMany('User as Users', array(
'local' => 'group_id',
'foreign' => 'user_id',
'refClass' => 'UserGroup'
));
}
}
// UserGroups
<?php
class UserGroup extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('user_id', 'integer', 4, array(
'primary' => true
)
);
$this->hasColumn('achievement_id', 'integer', 4, array(
'primary' => true
)
);
$this->hasColumn('date_completed', 'timestamp', 25);
}
}
and now all i want to do is build the relationship inside my controller:
$user = Doctrine::getTable('User')->findOneByEmail('abcd123#gmail.com');
$group = Doctrine::getTable('Group')->findOneByID('1');
$user->Group = $user;
Both SQL commands are returning one result and when I run the controller I get the following error:
Fatal error: Uncaught exception 'Doctrine_Record_UnknownPropertyException' with message 'Unknown record property / related component "User" on "Group"' in
The refclass option in the User and Group classes should most likely be UserGroup and not UserGroups (Doctrine doesn't understand the difference between singular and plural). You should also invoke the parent::setUp() method in each of the setup() methods you declare.
There's an extensive amount of documentation on many-many relationships in the official manual. (Which uses the user-group relation as an example)
EDIT:
I noticed some severe problems with the code while going through it again:
Your UserGroup table has an article_id column, but no group_id column.
The declared relation to the Group model under the name Groupss, this making the relation $user->Group unknown.
Finally, you should assign the user to an array of groups like $user->Groups[] = $group

Categories