Having multiple columns (foreign keys) of the same n-n relation in Backpackforlaravel - laravel

I'm struggling with the following situation:
My entities Session & Registration are related with a many-to-many (n-n) relationship. In Registration, I have two foreign keys, player_id and hotel_id.
In the Session CrudController, I want to display the related name(s) of the Player(s) and Hotel(s).
For Player, it worked like this:
CRUD::addColumn([
// any type of relationship
'name' => 'registrations', // name of relationship method in the model
'type' => 'relationship',
'label' => 'Spieler', // Table column heading
// OPTIONAL
'entity' => 'registrations', // the method that defines the relationship in your Model
'attribute' => 'player.full_name', // foreign key attribute that is shown to user
'model' => App\Models\Registration::class, // foreign key model
]);
So I've continued to add the Hotel like this:
CRUD::addColumn([
// any type of relationship
'name' => 'registrations', // name of relationship method in the model
'type' => 'relationship',
'label' => 'Hotel', // Table column heading
// OPTIONAL
'entity' => 'registrations', // the method that defines the relationship in your Model
'attribute' => 'hotel.name', // foreign key attribute that is shown to user
'model' => App\Models\Registration::class, // foreign key model
]);
But unfortunately it doesn't work - I don't get an error message, it just keeps showing only the Player column. I think the reason for this is the same value in 'name' - because after commenting the 'name' value in Player, the Hotel information was visible. But I have no idea how to avoid it.
Currently I'm not sure if it's a bug or if I'm doing anything wrong. Would appreciate any kind of support - thanks in advance!

thank you #tabacitu, that works!
I've added
'key' => 'hotel'
and it showed up in the table.

Related

Many-To-Many Relationship in backpack 4.1 for laravel

I use laravel 8 and backpack 4.1 for laravel. I have to add in one column more then one comma-separated-values. I have one pivot table with 2 foreign keys. The user can see with foreign key the available objects. I have to put all available objects into one column in setupListOperation() in CrudController of the user. How can I do it?
UserModel:
public function Objects(): belongsToMany
{
return $this->belongsToMany(Object::class);
}
CRUD::column('object_id')
->type('relationship')
->relation_type('BelongsToMany')
->model(Object::class)
->entity('name')
->label('Objects');
Thank you for your answers in advance.
I have found another method for the user crud. This method supposed to get the values from the method of the model.
$this->crud->addColumn(
[
// run a function on the CRUD model and show its return value
'name' => 'rentalObjects',
'label' => 'RentalObjects', // Table column heading
'type' => 'model_function_attribute',
'function_name' => 'getRentalObjects',
'attribute' => 'name'
]);
Method in the model User:
public function getRentalObjects(): string
{
$users = User::all();
foreach ($users as $user) {
$rentalObjects = $user->rentalObjects;
foreach ($rentalObjects as $rentalObject) {
$objectsNames = $rentalObject->name;
}
$objects = implode(",", array($objectsNames));
}
return $objects;
}
I coudn't see the new column on the small screen und thought, that the column wasn't in the table. By backpack one can choose the columns, if the screen is small.
The problem was solved:
$this->crud->addColumn([
'label' => 'Objekte', // Table column heading
'type' => 'select_multiple',
'name' => 'rentalObjects', // the method that defines the relationship in your Model
'entity' => 'rentalObjects', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => 'App\Models\RentalObject', // foreign key model
]);

save both field same name relationship one to one backpack laravel

I have two tables with relationship one to one hasOne and have column same name
CRUD::addField([
'label' => "Title",
'type' => 'text',
'name' => 'new_title', // the db column for the foreign key
]);
CRUD::addField([
'label' => "Title",
'type' => 'text',
'name' => 'achive.new_title', // the db column for the foreign key
'entity' => 'achive',
]);
I just want show once but save both to two table
You need something that's call the callbacks method, the simplicity of that method is you can control what you want after create, edit, delete and etc.
So, in your controller just need one field name,
CRUD::addField([
'label' => "Title",
'type' => 'text',
'name' => 'new_title',
]);
After that, you can create a new trait in your controller for creating/updating your relationship,
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
And then, declare the store function,
public function store() {
// Get the value from the request
$request = $this->crud->getRequest();
// And then you can insert/update data into your relationship table
\DB::table('achives') // Your relation table
->updateOrInsert(
['new_title' => $request->new_title],
['other_column_name' => 'Value of your other column']
);
$response = $this->traitStore();
// do something after save
return $response;
}
The updateOrInsert method accepts two arguments: an array of conditions by which to find the record, and an array of column and value pairs indicating the columns to be updated. more info here

Show/hide fields based on value of another field

I have a scenario where a field should be shown as dropdown or text field based on the value of another field.
Example:
User to select State as dropdown (California, North Carolina, etc) if the selected country is USA.
If any other country is selected (other than USA), user should be shown only a editable text field (instead of dropdown).
Please let me know if there is a way to achieve this using backpack's out-of-the box features. If not, is there any workaround possible?
My code snippet:
COUNTRY FIELD FROM DB:
CRUD::addField([
// 1-n relationship
'name' => 'countryid', // the column that contains the ID of that connected entity;
'label' => 'Country', // Table column heading
'type' => 'select2',
'entity' => 'getcountryid', // the method that defines the relationship in your Model
// optional
//'attribute' => 'name', // foreign key attribute that is shown to user
'model' => "App\Models\Country", // foreign key model
]);
STATE FIELD WHICH DEPENDS ON COUNTRY FIELD
(THIS SHOULD BE MADE AS A TEXT FILED OR DROPDOWN BASED ON THE COUNTRY SELECTED):
CRUD::addField([ // select2_from_ajax: 1-n relationship
'label' => "State", // Table column heading
'type' => 'select2_from_ajax',
'name' => 'countrystateid', // the column that contains the ID of that connected entity;
'entity' => 'countrystate', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'data_source' => url('/api/countrystate'), // url to controller search function (with /{id} should return model)
'placeholder' => 'Select an Indian state', // placeholder for the select
'minimum_input_length' => 0, // minimum characters to type before querying results
'dependencies' => ['countryid'], // when a dependency changes, this select2 is reset to null
//'method' => 'GET', // optional - HTTP method to use for the AJAX call ]); (GET, POST)
]);

Adding Columns with nested relationships in backpack for laravel

I have 3 models created in backpack for laravel CRUD:
Driver, Municipality and Province.
Driver has a 'municipality_id' and the relationship function:
public function municipality()
{
return $this->belongsTo('App\Models\Municipality');
}
To get the province of the driver i need to use a relationship function inside Municipality model:
public function province()
{
return $this->belongsTo('App\Models\Province');
}
The driver model does not contain the province function so i have to to something like
$objdriver->municipality->province->name;
To get the province name.
Now the problem is that i have to add 2 columns in the table created by artisan that display the municipality name and the province name.
For the municipality it's easy and i did it like this:
$this->crud->addColumn('municipality_id', [
// 1-n relationship
'label' => "Comune", // Table column heading
'type' => "select",
'name' => 'municipality_id', // the column that contains the ID of that connected entity;
'entity' => 'municipality', // the method that defines the relationship in your Model
'attribute' => "name", // foreign key attribute that is shown to user
'model' => "App\Models\Municipality", // foreign key model
]);
And it works Fine, but how do i add a column for the Provinces? Since the method is not in the driver model i can't use the same approach.
I already tried using a custom function to fetch what i need from the province table, something like:
$this->crud->addColumn('province_id', [
// run a function on the CRUD model and show its return value
'name' => "province_id",
'label' => "Provincia", // Table column heading
'type' => "model_function",
'function_name' => 'GetProvinceName', // the method in your Model
])
where GetProvinceName is:
public function GetProvinceName()
{
return $this->municipality->province->name;
}
but that just gives out an error.
You could try the following code.
$this->crud->addColumn([
'name' => 'municipality.province.name', // the relationships are handled automatically
'label' => 'Provincia', // the grid's column heading
'type' => 'text'
]);

Laravel Backpack select2_multiple not Displaying Correctly

I'm working with Backpack for Laravel, and implemented a select2_multiple field. The field works correctly, though it doesn't display properly at all. It's defined as:
$this->crud->addField([ // Select2Multiple = n-n relationship (with pivot table)
'label' => "Categories",
'type' => 'select2_multiple',
'name' => 'categories', // the method that defines the relationship in your Model
'entity' => 'categories', // the method that defines the relationship in your Model
'attribute' => 'title', // foreign key attribute that is shown to user
'model' => "App\Models\Category", // foreign key model
'pivot' => true // on create&update, do you need to add/delete pivot table entries?
]);
The pivot tables exist, as do the relationships on the models. The field shows for a second, and then in quickly hidden on page load (I guess by some JS). You can see below the 'categories' label, there's just white space:
I can, however, click in the white space and it will then appear and allow me to select categories as expected (though it displays rather strangely):
This is all default functionality, I haven't edited the select2_multiple template or any of the JS. Why is this displaying so poorly?
I believe it was a bug that has since been fixed. A composer update should fix it for you.
Is the model correct?
Maybe should be
'model' => "App\Category", // foreign key model

Resources