Migration for creating join table - php

There's a table in my SQL DB called "projects" and it has a column in it "categories" which is a varchar(255) representation of a php array "['category_1', 'category_2', 'category_3']" and what i'd like to do is put these categories into a separate table which would be made of a unique integer id in addition to the name of the category and then use a join table to connect it to "projects" in a many-to-many relationship.
So it would be a migration that would perform the following:
Create a join table called "categories_projects"
Create a table called "categories" that would be comprised of just a unique id and the title of the category
Insert into the categories a row for each so "category_1", "category_2", "category_3"
Look for any existing rows in the "projects" table and based on the varchar(255) field "category" mentioned above, create a row in the join table that would connect it to its respective category.
What I have so far:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('parent_id')->nullable();
$table->string('title');
$table->timestamps();
$table->softDeletes();
});
DB::table('categories')->insert(
[
'title' => 'category_1'
], [
'title' => 'category_2'
], [
'title' => 'category_3'
], [
'title' => 'category_4'
], [
'title' => 'category_5'
]
);
Schema::create('categories_projects', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('project_id');
$table->unsignedInteger('category_id');
$table->timestamps();
$table->softDeletes();
});
// This doesn't work but it's a representation of what I'm trying to do
// $categories = DB::rawQuery('select * from categories');
// foreach ($categories as $category) {
// $projects = DB::rawQuery('select * from projects where projects.category like %$category['title']');
// foreach($projects as $project) {
// DB::table(categories_projects)->insert(['project_id' => $project['id'], 'category_id' => $category['id']]);
// }
//
// }
}

Try this one:
If both sides of your categories name in your main table are surrounded by single quotes (such as 'category_1')
$categories = DB::rawQuery("select * from categories");
foreach ($categories as $category) {
$projects = DB::rawQuery("select * from projects where category like '%''" . $category["title"] . "''%' ");
foreach($projects as $project) {
DB::table('categories_projects')->insert(['project_id' => $project['id'], 'category_id' => $category['id']]);
}
}

This is what I ended up going with, it seems like I answered my own question in the process of asking it but anyways:
public function up()
{
Schema::dropIfExists('categories');
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->timestamps();
$table->softDeletes();
});
DB::table('categories')->insert([
['title' => 'Addition'],
['title' => 'Bathrooms'],
['title' => 'Commercial'],
['title' => 'Community'],
['title' => 'Dental'],
['title' => 'Design & Construction'],
['title' => 'Facade'],
['title' => 'Home Design'],
['title' => 'Medical'],
['title' => 'Multi-Family'],
['title' => 'Office'],
['title' => 'Renovation'],
['title' => 'Residential'],
['title' => 'Restaurant'],
['title' => 'Retail'],
['title' => 'Student Housing']
]);
Schema::create('categories_projects', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('project_id');
$table->unsignedInteger('category_id');
$table->timestamps();
$table->softDeletes();
});
$categories = DB::table("categories")->get();
foreach ($categories as $category) {
$category_id = $category->id;
$projects = DB::table('projects')->where('categories', 'like', '%'.$category->title.'%')->get();
$category_proj = [];
foreach ($projects as $project) {
$project_id = $project->id;
$category_proj[] = ['project_id' => $project_id, 'category_id' => $category_id];
}
DB::table('categories_projects')->insert($category_proj);
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('categories_projects');
Schema::dropIfExists('categories');
}

Related

How can i insert tags in post_table and Tags table?

I want to insert tags in Tags table as well as post_tag table from post creating page. When i create a new post tags are inserting in Tags table but not inserting in post_tag tablbe. it is showing Invalid datetime format.
SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: 'start,tas' for column anusondhan.post_tag.tag_id at row 1 (SQL: insert into post_tag (post_id, tag_id) values (20, start,tas))
//Store Post
public function storeNewPost(Request $request){
//return $request->all();
$request->validate([
'post_title' => 'required',
'post_details' => 'required',
'category_id' => 'required',
'image' => 'image|max:15360|dimensions:max_width=4000,max_height=3000'
]);
$image = $request->file('post_thumbnail');
$name_gen=uniqid().'.'.$image->getClientOriginalExtension();
Image::make($image)->resize(700,400)->save('frontend/assets/images/post/'.$name_gen);
$save_url = 'frontend/assets/images/post/'.$name_gen;
$post = Post::create([
'user_id' => Auth::id(),
'post_uper_title' =>$request->post_uper_title,
'post_title' =>$request->post_title,
'post_sub_title' =>$request->post_sub_title,
'post_details' =>$request->post_details,
'post_slug' =>str_replace(' ', '-', $request->post_title),
'seo_title' =>$request->seo_title,
'seo_descp' =>$request->seo_descp,
'lead' =>$request->lead,
'lead2' =>$request->lead2,
'featured' =>$request->featured,
'repoter_name' =>$request->repoter_name,
'division_id' =>$request->division_id,
'district_id' =>$request->district_id,
'category_id' =>$request->category_id,
'post_thumbnail' =>$save_url,
'thumbnail_caption' =>$request->thumbnail_caption,
'thumbnail_alt' =>$request->thumbnail_alt,
'created_at' => Carbon::now(),
]);
if($post){
$tags = explode(",", implode($request->tags));
$tagNames = [];
if (!empty($tags)) {
foreach ($tags as $tagName)
{
$tag = Tags::firstOrCreate(['name'=>$tagName]);
if($tag)
{
$tagNames[] = $tag->id;
}
}
}
$post->tags()->sync($request->tags);
$notification = array(
'message' => 'Post Inserted Successfully',
'alert-type' => 'success'
);
return redirect()->route('all.posts')->with($notification);
}else{
return back();
}
}//end insert post
** Here is my Tags table **
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('slug')->nullable();
$table->longText('description')->nullable();
$table->longText('tag_thumb')->nullable();
$table->text('thumb_caption')->nullable();
$table->text('thumb_alt')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
** Here is my Post_tag Table **
public function up()
{
Schema::create('post_tag', function (Blueprint $table) {
$table->increments('id');
$table->unsignedBigInteger('post_id')->nullable();
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->unsignedBigInteger('tag_id')->nullable();
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->timestamps();
});
}
I think you need to use $tagNames array instead of $request->tags when syncing:
$post->tags()->sync($tagNames);
As per the Laravel documentation, the sync() method expects an array of IDs:
https://laravel.com/docs/8.x/eloquent-relationships#syncing-associations
If you have manyToMany relation in your models use sync() method on update function in your controller.
Example: $post->tags()->sync($request->tags);
If you need more help tell me.

store uploaded images into database laravel 8

i have a product and i want it to have multiple file, so i made a oneToMany relation between product and images model.
i was able to upload image successfully
public function uploadFile(Request $request)
{
if($request->hasFile('images'))
{
foreach($request->file('images') as $file)
$file->store('public/images/'. $file->getClientOriginalName());
}
return $request->file('images');
}
now images are storage into storage/public/~ i want to them them to database
Here is my store function in ProductController
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'price' => 'required|numeric',
'description' => 'required',
'category' => 'required',
'attribute' => 'required',
'stocks' => 'required|numeric',
//'discounts' => 'required|numeric'
]);
$product = Product::create($request->only('name','price','description', 'tag', 'category', 'attribute'));
$product->stocks()->create([
'quantity' => $request->stocks,
'product_id' => $product->id
]);
$product->discounts()->create([
//'discount' => $request->discounts,
'product_id' => $product->id
]);
/*
foreach( $request->file('images') as $file)
{
$product->images()->create([
'product_id' => $product->id,
'file_path' => $file->hashName()
]);
}
*/
}
what should i add to it so i be able to store image into the table
update
images table schema
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('file_path');
$table->timestamps();
$table->foreignId('product_id')->constrained('products')->onUpdata('cascade')->onDelete('cascade');
});
product table schema
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->double('price');
$table->string('category');
$table->string('attribute');
$table->text('description');
$table->string('tag');
$table->timestamps();
});
You can do some think like below
$images=[];
foreach($request->file('images') as $file){
$fileName = time().Str::random(8).'.'.$file->getClientOriginalExtension();
$file->store('public/images/'.$fileName);
$images[]=['file_path'=>$fileName] ;
}
$product->images()->createMany($images);
I hope you have hasmany relationship in product model

Laravel : Create new product with category in database

for the moment, i'am creating my product link to my category directly from my code in my seed doing
->categories()->attach(1) at the end of each product.
From my database, I can create a product but i can't link them with a foreign key to a category that is already in category_product_table.
I have 3 table : products, categories and category_product.
2020_04_09_073846_create_products_table
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned()->index();
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->string('name');
$table->string('slug');
$table->string('category');
$table->string('description');
$table->string('releaseDate');
$table->float('price');
$table->timestamps();
});
}
ProductSeeder
<?php
use Illuminate\Database\Seeder;
use App\Product;
class ProductSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Product::create([
'name' => 'Halo 5',
'slug' => 'halo-5',
'category_id' => '1',
'category' => 'Xbox One',
'description' => "Halo 5: Guardians sur Xbox One est un FPS mettant en scène les aventures du Master Chief et d'un nouveau personnage, le Spartan Jameson Locke. ",
'releaseDate' => '27 octobre 2015',
'price' => '54.99'
]);
2020_05_02_201337_create_categories_table
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('slug')->unique();
$table->timestamps();
});
}
CategorieSeeder
<?php
use Carbon\Carbon;
use App\Category;
use Illuminate\Database\Seeder;
class CategorieSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$now = Carbon::now()->toDateTimeString();
DB::table('categories')->insert(
array(
array(
'name' => 'Xbox',
'slug' => 'xbox',
),
array(
'name' => 'Playstation',
'slug' => 'playstation',
),
array(
'name' => 'PC',
'slug' => 'pc',
),
array(
'name' => 'Switch',
'slug' => 'switch',
),
)
);
}
}
2020_05_03_105839_create_category_product_table
public function up()
{
Schema::create('category_product', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned()->nullable();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->integer('category_id')->unsigned()->nullable();
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->timestamps();
});
}
Product.php
class Product extends Model
{
public function categories()
{
return $this->AsOne('App\Category');
}
}
Category.php
class Category extends Model
{
public function products()
{
return $this->belongsToMany('App\Product');
}
}
HomeController
public function public(){
if (request()->category) {
$home = Product::with('categories')->whereHas('categories', function ($query){
$query->where('slug', request()->category);
})->get();
$categories = Category::all();
$categoryName = $categories->where('slug', request()->category)->first()->name;
} else {
$home = Product::inRandomOrder()->paginate(9);
$categories = Category::all();
$categoryName = 'Featured';
}
return view('home.index')->with([
'home' => $home,
'categories' => $categories,
'categoryName' => $categoryName,
'mode' => 'public'
]);
If someone can help me, thanks for your help !
php artisan make:migration create_products_table --create=products
php artisan migrate:refresh
use directly this command and add

Laravel: Integrity constraint violation

I'm studying some Laravel and at some point I had to re-migrate the database because I had to change a table. I'm using postman to do testing, and one of the api methods give me the error:
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: events.user_id (SQL: insert into "events" ("sport", "title", "players", "when", "description", "location", "updated_at", "created_at") values (Hockey, Grass Hockey, 12, 30/09/2018, Come join us, Fairview park, 2018-11-08 22:19:45, 2018-11-08 22:19:45))
so it seems to be a problem with the events.user_id which I changed on a table called Events to have a relationship with the Users table. Some examples I found by researching is on table fields that were not ids, so I don't how to figure this one out, maybe some of you can help me!
here are the migrations for Events and Users:
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->string('sport');
$table->string('title');
$table->decimal('players', 8, 2);
$table->date('when');
$table->mediumText('description');
$table->string('location');
$table->timestamps();
});
}
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Here are the models:
class Event extends Model
{
protected $fillable = [
'sport',
'title',
'players',
'when',
'description',
'location'
];
public function user()
{
return $this->belongsTo('App\User');
}
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function events()
{
return $this->hasMany('App\Event');
}
}
And below is the api method that is giving me the error:
Route::post('/admin/create-event', function (Request $request) {
$data = $request->all();
$event = Event::create(
[
'sport' => $data['sport'],
'title' => $data['title'],
'players' => $data['players'],
'when' => $data['when'],
'description' => $data['description'],
'location' => $data['location'],
]
);
return $event;
});
Thanks guys!
Edit:
Route::middleware('auth:api')->post('/admin/create-event', function (Request $request) {
$user = $request->user();
$data = $request->all();
$event = Event::create(
[
'user_id' => \Auth::user()->id,
'sport' => $data['sport'],
'title' => $data['title'],
'players' => $data['players'],
'when' => $data['when'],
'description' => $data['description'],
'location' => $data['location'],
]
);
return $event;
});
I think you have to add 'user_id' to $fillable of Event class:
class Event extends Model
{
protected $fillable = [
'sport',
'title',
'players',
'when',
'description',
'location',
'user_id'
];
public function user()
{
return $this->belongsTo('App\User');
}
}
You need to pass the user_id:
'user_id' => \Auth::user()->id
The example above requires an authenticated user in the session, but if you are making the request using postman you probably don’t have one.
Anyway, you need to provide the user_id that will be stored in the database.
EDIT
Eloquent's method create will copy to the model only the attributes defined as fillable. So you have two options:
Add user_id to $fillable
Use newInstance instead of create, manually set the user_id with $event->user_id = ..., and manually save the $event model with $event->save();

Return count of a table's column via pivot table Laravel 5.2

So I have a user table, a role table and an intermediate table for those 2, user_role. It's a many-to-many relationship between the first 2 tables.
I want to return the count of the users which have a specific role but I can't seem to get it right.
My migrations:
user:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('email')->unique();
$table->string('username')->unique();
$table->string('password');
});
role:
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('name', 40);
$table->string('description', 255);
});
user_role:
Schema::create('user_role', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('user_id');
$table->integer('role_id');
});
Relationship between them:
public function users(){ //in role model
return $this->belongsToMany('App\User', 'user_role', 'role_id', 'user_id')->withTimestamps();
}
public function roles(){ //in user model
return $this->belongsToMany('App\Role', 'user_role', 'user_id', 'role_id')->withTimestamps();
}
Role Seeder:
public function run()
{
Role::create([
'id' => 1,
'name' => 'Admin',
'description' => 'Admin User.'
]);
Role::create([
'id' => 2,
'name' => 'Vendor',
'description' => 'Vendor User.'
]);
Role::create([
'id' => 3,
'name' => 'User',
'description' => 'Simple User.'
]);
}
in controller:
public function adminDashboard(){
$users = User::all();
return view('admin.dashboard')->withUsers($users);
}
in view:
{{ $users->count() }}
This obviously, returns the total count of users in user table. Any ideas on how to return the count of users which have a specific role?
use $role->users()->count()
To iterate over the roles and display the count of users, you can use this:
public function adminDashboard(){
$roles = App\Role::all();
return view('admin.dashboard', compact('roles'));
}
In your dashboard view:
#foreach ($roles as $role)
<p>Role {{ $role->name }} has {{ $role->users()->count() }} users</p>
#endforeach

Categories