give category id to subcategory in laravel seed - laravel

I try to add data with seed in laravel 5.4, let's say I have 10 category and I added them by seed to my database now I also have another seed for subcategories but before I add my subcategories I want to tell which one is belongs to what category that I imported before. how would I do that?
Update:
I found my question might be confusing for some people so i try to explain a bit more,
this is my category seed.
<?php
use Illuminate\Database\Seeder;
class CategoriessTableSeeder extends Seeder {
public function run()
{
DB::table('categories')->delete();
$categories = array(
array('name' => 'Accounting/Finance', 'slug' => 'hccounting_finance'),
array('name' => 'Admin/Human Resources', 'slug' => 'admin_human_resources'),
array('name' => 'Arts/Media/Communications', 'slug' => 'arts_media_communications'),
array('name' => 'Building/Construction', 'slug' => 'building_construction'),
array('name' => 'Computer/Information Technology', 'slug' => 'computer_information_technology'),
array('name' => 'Education/Training', 'slug' => 'education_training'),
array('name' => 'Engineering', 'slug' => 'engineering'),
array('name' => 'Healthcare', 'slug' => 'healthcare'),
array('name' => 'Hotel/Restaurant', 'slug' => 'hotel_restaurant'),
array('name' => 'Manufacturing', 'slug' => 'manufacturing'),
array('name' => 'Sales/Marketing', 'slug' => 'sales_marketing'),
array('name' => 'Sciences', 'slug' => 'sciences'),
array('name' => 'Services', 'slug' => 'services'),
array('name' => 'Others', 'slug' => 'others'),
);
DB::table('categories')->insert($categories);
}
}
I have another similar with this for subcategories here it is:
<?php
use Illuminate\Database\Seeder;
class SubategoriessTableSeeder extends Seeder {
public function run()
{
DB::table('subcategories')->delete();
$subcategories = array(
array('name' => 'Audit & Taxation Jobs', 'slug' => 'audit_taxation_jobs', 'category_id' => ''),
);
DB::table('subcategories')->insert($subcategories);
}
}
in this sample 'category_id' => '' has to get the id/name of 'Accounting/Finance category in category seed .
now my question is how?
UPDATE 2:
Error's
[Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity
constraint violation: 1451 Cannot delete or update a parent row: a
foreign key constraint fails (jobid.ads, CONSTRAINT ads_subcateg
ory_id_foreign FOREIGN KEY (subcategory_id) REFERENCES
subcategories (id)) (SQL: delete from subcategories)
[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails
(jobid.ads, CONSTRAINT ads_subcateg
ory_id_foreign FOREIGN KEY (subcategory_id) REFERENCES subcategories (id))
Code used:
<?php
use Illuminate\Database\Seeder;
use Carbon\Carbon;
class SubcategoriesTableSeeder extends Seeder {
public function run()
{
DB::table('subcategories')->delete();
$categoryFinance = Category::select("id")->whereSlug("hccounting_finance")->firstOrFail();
$subcategories = array(
array('name' => 'Audit & Taxation Jobs', 'category_id' => $categoryFinance, 'slug' => 'audit_taxation_jobs', 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), 'updated_at' => Carbon::now()->format('Y-m-d H:i:s')),
array('name' => 'Banking/Financial Jobs', 'category_id' => $categoryFinance, 'slug' => 'banking-financial_jobs', 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), 'updated_at' => Carbon::now()->format('Y-m-d H:i:s')),
array('name' => 'Corporate Finance/Investment Jobs', 'category_id' => $categoryFinance, 'slug' => 'corporate_finance_investment_jobs', 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), 'updated_at' => Carbon::now()->format('Y-m-d H:i:s')),
array('name' => 'General/Cost Accounting Jobs', 'category_id' => $categoryFinance, 'slug' => 'general_cost_accounting_jobs', 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), 'updated_at' => Carbon::now()->format('Y-m-d H:i:s')),
);
$categoryAdmin = Category::select("id")->whereSlug("admin_human_resources")->firstOrFail();
$subcategories = array(
array('name' => 'testing', 'slug' => 'tesingsubs', 'category_id' => $categoryAdmin, 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), 'updated_at' => Carbon::now()->format('Y-m-d H:i:s')),
);
DB::table('subcategories')->insert($subcategories);
}
}

In order to relate your categories to subcategories, you should follow the logic (depending on your relationship - N-1 N-N) in the docs (https://laravel.com/docs/5.4/eloquent-relationships). It seems that you need the attach() method.
So after creating the category entry, if you have followed the schema convention you can apply logic for all kind or relationships, even for polymorphic ones.
Edit:
After your edit it seems that you need a way to access the entries of your table again in order to relate them.
So, you can :
$categoryFinance = Category::select("id")->whereSlug("hccounting_finance")->firstOrFail();
in your SubategoriessTableSeeder run() function before creating your array.
And then give that id in your subcategory_id. The same will be for all categories you need to relate.
Edit 2
Please check again that your foreign keys are correct. In that case you cannot delete the subcategories table because Categories "need" subid. And that's where constraint violation comes from. You don't need to delete these tables.. You just need to "feed-seed" them.
So try to remove the "delete" statements.
Edit 3
I think the error is obvious now.. There is no Category with id of 2 in your database. But again, check if the keys are associated correctly (this is an SQL and not a Laravel issue).
Run migrations if any, and seeders again, with the correct order (first categories and then subcategories - first the dependency and then the dependent one in general)

Related

SQLSTATE[HY000]: General error: 1364 Field 'seller_id' doesn't have a default value

$product = new Product([
'productName' => $request->productName,
'quantity' => $request->quantity,
'weight' => $request->weight,
'boxes' => $request->boxes,
'MRP' => $request->MRP,
'costprice' =>$request->costprice,
'productDescription' =>$request->productDescription,
'seller_id' => $request->user('seller')->id,
'category_id' => $request->category
]);
$product->save();
I have provided values to the product table but still it is showing this error SQLSTATE[HY000]: General error: 1364 Field 'seller_id' doesn't have a default value (SQL: insert into products (updated_at, created_at) values (2021-12-30 13:35:47, 2021-12-30 13:35:47))
Try this instead:
$product = Product::create([
'productName' => $request->productName,
'quantity' => $request->quantity,
'weight' => $request->weight,
'boxes' => $request->boxes,
'MRP' => $request->MRP,
'costprice' =>$request->costprice,
'productDescription' =>$request->productDescription,
'seller_id' => $request->user('seller')->id,
'category_id' => $request->category
]);
$product should be saved now. Assuming your $request->user('seller')->id actually has data, and assuming your attributes you are filling out are all fillable. mass assignment docs

Pagination with many to many relationships

I have products, categories and category_product (pivot) tables in my database.
I want to return the category info and products with pagination in the same response.
I know I can use Product::with('categories')->pagination(20),
but I don't want to attach the category to each product.
What is the proper way to get products belong to a specific category?
I have tried that but I can't get the pagination with that:
$category = Category::where('slug', $slug)->first();
$products = $category->products()->paginate(20);
return response()->json([
'category' => new CategoryResource($category),
'products' => ProductResource::collection($products),
]);
Here is my ProductResource
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'code' => $this->code,
'image' => $this->image,
'quantity' => $this->quantity,
'price' => $this->price,
'slug' => $this->slug,
'sort_order' => $this->sort_order,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'categories' => CategoryResource::collection($this->whenLoaded('categories')),
];
This looks like an issue with the way data is returned from the Collection.
The easiest solution is:
return response()->json([
'category' => new CategoryResource($category),
'products' => ProductResource::collection($products)->response()->getData(true),
]);
You can try as below
$category = Category::where('slug', $slug)
->with('products', function($query) {
$query->paginate(20);
})
->first();
return response()->json([
'category' => new CategoryResource($category),
'products' => ProductResource::collection($category->products),
]);
Hope this is what you are looking for.

How is it possible to retrieve the id of a Model right after it was created in the same controller function?

Let me show you my code, and place comments for you guys to better understand:
$homework = new Homework([ // I create Homework (And I indeed want to get the ID of the one that was just created).
'subject_id' => $request->subject_id,
'user_id' => auth()->user()->id,
'title' => $request->name,
'image' => $path,
'progress' => $request->progress,
'description' => $request->description,
'duedate' => $request->date
]);
$homework->save(); // I save it
$homeworkid = Homework::where('id', $id)->first(); // I try to retrieve it, but I'm not sure how to get it as I need to define `$id`.
$progress = newProgress([
'user_id' => auth()->user()->id,
'homework_id' => $homeworkid, // I need this for the relationship to work.
'title' => 'Initial Progress',
'description' => 'This progress is auto-generated when you create an assignment',
'username' => auth()->user()->name,
'progress' => $homeworkid->progress
]);
$progress->save(); // I save the progress
Well, as you saw, I'm trying to retrieve the ID of Homework right after it was created, but I'm not sure how to define $id in order to get it.
There is no need to instantiate a new model and saving it if your are not doing anything between instantiating and saving, you can use the create method instead:
$homework = Homework::create([
'subject_id' => $request->subject_id,
'user_id' => auth()->user()->id,
'title' => $request->name,
'image' => $path,
'progress' => $request->progress,
'description' => $request->description,
'duedate' => $request->date
]);
$homework->id; // get the id
After saving / creating the model you can access the id like you normally would:
$homework->id
What you then could do is setup the relationships between your models so you can do the following after creating a new homework:
$homework->newProgress()->create([
'user_id' => auth()->user()->id,
'title' => 'Initial Progress',
'description' => 'This progress is auto-generated when you create an assignment',
'username' => auth()->user()->name,
'progress' => $homework->progress
]);
This way you don't have to pass the homework id when creating a new newProgress, laravel will pass it automatically for you.
This is very simple for you. No need to complex it.
$homework->save(); // I save it
After this line just use only
$progress = newProgress([
'user_id' => auth()->user()->id,
'homework_id' => $homework->id, // I need this for the relationship to work.
'title' => 'Initial Progress',
'description' => 'This progress is auto-generated when you create an assignment',
'username' => auth()->user()->name,
'progress' => $homework->progress
]);
You don't no need this line of code
$homeworkid = Homework::where('id', $id)->first(); // I try to retrieve it, but I'm not sure how to get it as I need to define `$id`.
$data = $homework->save();
Get the ID this way: $data->id

How can I maintain foreign keys when seeding database with Faker?

Below is my model factory.
$factory->define(App\Business::class, function (Faker\Generator $faker){
return [
'name' => $faker->bs,
'slug' => $faker->slug,
'address' => $faker->streetAddress,
'phone_no' => $faker->phoneNumber,
'mobile_no' => $faker->phoneNumber,
'email' => $faker->companyEmail,
'website' => $faker->domainName,
'latitude' => $faker->latitude,
'longitude' => $faker->longitude,
'location' => $faker->city,
'business_days_from' => $faker->dayOfWeek,
'business_days_to' => $faker->dayOfWeek,
'description' => $faker->text,
'user_id' => $faker->factory(App\User::class),
];
});
and This my database seeder class
class DatabaseSeeder extends Seeder
{
public function run()
{
factory(App\Business::class, 300)->create();
}
}
But when I execute php artisan db:seed ...it does not work..
What should be the workaround here..any help would be appreciated..
you can get all ids using pluck (lists is depricated for laravel >= 5.2)
$userIds = User::all()->pluck('id')->toArray();
and get a random id for FK column:
'user_id' => $faker->randomElement($userIds)
You may also attach relationships to models using Closure attributes in your factory definitions.
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
I just found the workaround .. I replaced
'user_id' => $faker->factory(App\User::class),
with
'user_id' => $faker->randomElement(User::lists('id')->toArray()),
and that solves the problem for now..

Laravel seeding preg_replace(): error

I was wondering if someone can help me.
I am having trouble seeding a database in laravel using seeder, it keeps throughing this error:
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
When running php artisan db:seed
the seeder in question is: GroupTableSeeder.php and the code in the file is:
<?php
class GroupTableSeeder extends Seeder {
public function run()
{
DB::table('groups')->truncate();
$permissions = array( 'system' => 1, );
$group = array(
array(
'name' => 'agency',
'permissions' => $permissions,
'created_at' => new DateTime,
'updated_at' => new DateTime
),
);
DB::table('groups')->insert($group);
}
}
In the DatabaseSeeder.php I have:
public function run()
{
Eloquent::unguard();
$this->call('GroupTableSeeder');
$this->command->info('Group table seeded!');
}
I am trying to populate the Groups table with a user role I am currently using https://cartalyst.com/manual/sentry#groups
Any help would be much appreciated.
Cheers,
Chris
Found the answer, I needed to do:
Sentry::getGroupProvider()->create(array(
'name' => 'Agency',
'permissions' => array('admin' => 1),
));
Instead of:
$permissions = array( 'system' => 1, );
$group = array(
array(
'name' => 'agency',
'permissions' => $permissions,
'created_at' => new DateTime,
'updated_at' => new DateTime
),
);

Resources