Creating Seeder with foreign key field Laravel 5.3 - laravel

I'm trying to create a seeder for my table addresses but one field of my table, is a foreign key, This Fk references a user id of my table users.
My Seeder Class:
class AddressesSeeder extends Seeder
{
public function run()
{
$faker = Faker::create();
// following line retrieve all the user_ids from DB
$users = User::all()->pluck('id');
foreach(range(1,50) as $index){
$address = Address::create([
'user_id' => $faker->randomElement($users),
'street' => $faker->street,
'number' => $faker->number,
'city' => $faker->city,
'state' => $faker->state,
'created_at' => $faker->datetime,
'updated_at' => $faker->datetime,
]);
}
}
}
When i run the db:seed, i receave the error:
[ErrorException]
Argument 1 passed to Faker\Provider\Base::randomElements() must be of the type array, object given, called in C:\xampp\htdocs\projeto\vendor\fzaninotto\fake
r\src\Faker\Provider\Base.php on line 205 and defined

It's because pluck() will return an object, use toArray() to parse it.
$users = User::all()->pluck('id')->toArray();

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
]);

Laravel 9 factory and creating related 1:1 models

I'd like to use Laravel factories to populate some dummy data in my test environment. I have a Locations model and a LocationDetails model, which have a 1:1 relationship and a record needs to be created in the LocationDetails table whenever a new Location is created.
How can I do this in a factory such that there's exactly 1 LocationDetails record for each Location record.
Here's what I have in my DatabaseSeeder class:
if(env('APP_ENV') === 'local') {
Client::factory()->count(25)->create();
Location::factory()->count(30)->create();
}
My location factory definition:
public function definition()
{
return [
'name' => $this->faker->company,
'client_id' => Client::all()->random()->id,
'location_status_id' => LocationStatus::all()->random()->id,
'address' => $this->faker->streetAddress,
'city' => $this->faker->city,
'state' => $this->faker->StateAbbr,
'zip_code' => $this->faker->numerify('#####'),
'phone' => $this->faker->numerify('###-###-####'),
'email' => $this->faker->safeEmail,
'is_onboarding_completed' => 1,
];
}
It looks like Laravel has an afterCreate() callback for a factory, but I'm just not clear on how to accomplish this.
Does this work
Location::factory()
->has(LocationDetails::factory())
->count(30)
->create();
Or you can have a state defined on the LocationFactory
//LocationFactory
//Assuming location_id is the foreign key on LocationDetails model
public function withLocationDetail()
{
return $this->afterCreating(function (Location $location) {
LocationDetails::factory()->create(['location_id' => $location->id]);
});
}
And then use it like
Location::factory()
->withLocationDetail()
->count(30)
->create();

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'
]);

Include related table from pivot table in Fractal's Transformers

In my Laravel project, I have 4 tables:
location
location_product
product
status
location_product is the intermediate table between location and product and it has a foreign key status pointing to the product_status table.
I'm using Fractal's transformers to transform my models:
//Filter the products
$products = $location->products()->unarchived()->get();
return $this->response()->collection($products, new ProductDetailsTransformer());
and in my ProductDetailsTransformer.php, I want to include the status from the intermediate table using '''defaultIncludes''':
/**
* List of resources to automatically include
*/
protected $defaultIncludes = [
'status',
];
public function includeStatus(Product $product) {
return $this->item($product->pivot->status, new ProductStatusTransformer());
}
but I receive an
Call to undefined relationship [status] on model [App\Models\Product].
How can I correctly include the status table using Fractal's transformers?
At the moment, I'm using the following:
public function transform(Product $product) {
return [
'id' => (int)$product->id,
'name' => $product->name,
'amount' => $product->pivot->amount,
'delivery_on_site' => (bool)$product->pivot->delivery_on_site,
'status' => [
'id' => $product->pivot->status->id,
'name' => $product->pivot->status->name
]
];
}
But I'd like to use a Transformer if that's possible for the status.

ErrorException in CrudTrait.php Undefined offset: 0 Backpack for Laravel 5.2

i want create dynamic combobox from database, but i have an error with this message :
ErrorException in CrudTrait.php line 32: Undefined offset: 0 (View: /home/vagrant/Code/hrd/resources/views/vendor/backpack/crud/fields/select2.blade.php) (View: /home/vagrant/Code/hrd/resources/views/vendor/backpack/crud/fields/select2.blade.php) (View: /home/vagrant/Code/hrd/resources/views/vendor/backpack/crud/fields/select2.blade.php)
This is my DistrictCrudController.php :
<?php
namespace App\Http\Controllers\Admin;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use App\Http\Requests\DistrictRequest as StoreRequest;
use App\Http\Requests\DistrictRequest as UpdateRequest;
class DistrictCrudController extends CrudController {
public function __construct() {
parent::__construct();
$this->crud->setModel("App\Models\District");
$this->crud->setRoute("admin/district");
$this->crud->setEntityNameStrings('district', 'districts');
$this->crud->setFromDb();
$this->crud->addField([
'label' => "City",
'type' => 'select2',// the method that defines the relationship in your Model
'name' => 'city_id', // the db column for the foreign key
'entity' => 'cities', //tabel entity
'attribute' => 'id', // foreign key attribute that is shown to user
'model' => "App\Models\City" // foreign key model
]);
}
public function store(StoreRequest $request)
{
return parent::storeCrud();
}
public function update(UpdateRequest $request)
{
return parent::updateCrud();
}
}
The code is run well if i remove :
$this->crud->addField([
'label' => "City",
'type' => 'select2',// the method that defines the relationship in your Model
'name' => 'city_id', // the db column for the foreign key
'entity' => 'cities', //tabel entity
'attribute' => 'id', // foreign key attribute that is shown to user
'model' => "App\Models\City" // foreign key model
]);
I use Backpack for Laravel 5.2
Not sure if it will solve, but i can only see two issues that might be causing that.
You don't have cities relationship defined or you could try using:
public function setUp()
{
$this->crud->setModel("App\Models\District");
$this->crud->setRoute("admin/district");
$this->crud->setEntityNameStrings('district', 'districts');
$this->crud->setFromDb();
...
...
don't use parent::__construct().
Give it a try and post your results if not solved.

Resources