I just started laravel but I'm stuck to this point and I don't find a way to do it
Basically I insert an article with a category.
With select2, I select an existing category or I create a new one.
My article model :
public function category(){
return $this->belongsTo('App\Category');
}
My categories model :
public function articles(){
return $this->hasMany('App\Article');
}
My article migration :
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('content')->nullable();
$table->timestamps();
});
}
My category migration :
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('nom')->unique();
});
Schema::table('articles', function(Blueprint $table){
$table->integer('category_id')->unsigned()->index();
});
And finally my controller function to store article (I want to use transaction) :
public function store(Request $request)
{
$this->validate($request, [
'numero' => 'required',
'category' => 'required',
'title' => 'required'
]);
$article = new Article();
DB::transaction(function() use ($request) {
$category = Category::firstOrCreate(['nom' => $request->input('category')]);
$article->title = $request->input('title');
$article->save();
});
return response()->json([
'title' => $article->title
]);
}
So I know I don't save category id into article db but my category doesn't even insert, on my debug bar I've got this :
Begin Transaction
select * from batiments where (nom = 'HI') limit 1
Rollback Transaction
And my post page give me this error :
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicata du champ '' pour la clef 'batiments_nom_unique' (SQL: insert into batiments () values ())
Someone knpw how to insert or select if exist category and insert is id into article table ?
Thank
$table->integer('category_id')->unsigned()->index();
You set this field as index, just remove index(). Identity field must have only unique records, but your category_id may have same value many times.
code:
$table->integer('categorie_id')->unsigned();
$table->foreign('categorie_id')->references('id')->on('categories');
Laravel provides support for creating foreign key constraints, which are used to force referential integrity at the database level. For example, let's define a categorie_id column on the articles table that references the id column on a categories table
laravel.com/docs/5.4/migrations#foreign-key-constraints
Related
Problem: I'm trying to query a PeopleType to find all the courses where a person isn't associated.
I have 4 tables
People
PeopleTypes
Courses
People_Courses
PeopleType_Courses
I have the following relationships
PERSON MODEL
public function getPeopleType() {
return $this->belongsTo('App\PeopleType','type_id');
}
public function getCourses() {
return $this->belpngsToMany('App\Course','People_Courses','person_id','course_id');
}
PEOPLE_TYPE MODEL
public function getPeople() {
return $this->hasMany('App\Person','type_id');
}
public function getCourses() {
return $this->belpngsToMany('App\Course','PeopleType_Courses','people_type_id','course_id');
}
My attempt:
$peopleType = \App\PeopleType::FindOrFail(1);
$courses = $peopleType->getCourses()->whereNotIn('id', function($q) use($person) {
$q->select('course_id')
->from('People_Courses')
->where('person_id', $person->id);
})->get();
My response:
Integrity constraint violation: 1052 Column 'id' in IN/ALL/ANY
subquery is ambiguous
People Courses Table Schematic
Schema::create('People_Courses', function (Blueprint $table) {
$table->increments('id');
$table->integer('course_id');
$table->integer('person_id');
);
PeopleType_Courses Table Schematic
Schema::create('PeopleType_Courses', function (Blueprint $table) {
$table->increments('id');
$table->integer('course_id');
$table->integer('people_type_id');
);
When you're working on relations that have similar column name being selected in the query you need to resolve the ambiguity by specifying the table name with the column. e.g:
$peopleType->getCourses()->whereNotIn('courses.id', function($q)... //courses.id
I have a question and the answers i have been getting are not really helping me.
So I have been trying to basically create a Profiles table for each users. I followed through the rules for One to One relationship but i keep getting this error
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into users (name, email, password, admin, updated_at, created_at) values (Darlington Okorie, darlingtonokoriec#gmail.com, $2y$10$Ob161LW8sbbv5uDv9VVbienlmW.DWXVDK3wdfC0I0NlnOrg1Jx/a2, 1, 2019-12-23 17:41:30, 2019-12-23 17:41:30))
Heres the code i wrote in my UsersTableSeeder
public function run()
{
$user = App\User::create([
'name' => 'Darlington Okorie',
'email' => 'darlingtonokoriec#gmail.com',
'password' => bcrypt('password'),
'admin' => 1
]);
App/Profile::create([
'user_id' => $user->id,
'avatar' => 'uploads/avatar/img.png',
'about' => 'Great at writing. Better at blogging',
'facebook' => 'facebook.com',
'youtube' => 'youtube.com'
]);
}
And i had also defined user_id in my create_users_table
public function up()
{
Schema::create('users', function (Blueprint $table) {
Schema::dropIfExists('users');
$table->bigIncrements('id');
$table->string('name');
$table->string('user_id');
$table->string('email')->unique();
$table->boolean('admin')->default(0);
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
And defined the user_id in my create_profiles_table
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('avatar');
$table->integer('user_id');
$table->text('about');
$table->string('facebook');
$table->string('youtube');
$table->timestamps();
});
}
What could be wrong?
I faced this kind of issue as well.
My Case, I forgot to write the field in fillable.
protected $fillable = [
'name',
];
After writing the field in $fillable. My Issue was solved.
This is an issue with your users migration, and not the profiles migration. Your migration has this line:
Schema::create('users', function (Blueprint $table) {
...
$table->string('user_id'); // This one
Which is creating a non-null varchar column called user_id. In your Seed file, you're not setting that, and null is not allowed. Add and configure the following line below:
$user = App\User::create([
'name' => 'Darlington Okorie',
'email' => 'darlingtonokoriec#gmail.com',
'password' => bcrypt('password'),
'admin' => 1,
'user_id' => 'SomeRandomString' // Add this, set to whatever is logical.
]);
Alternatively, set nullable() on your users migration:
Schema::create('users', function (Blueprint $table) {
$table->string('user_id')->nullable();
Honestly, unless you need a separate identifier for each User, your users table likely doesn't need a user_id, and you can remove it from the migration completely.
Edit: I'm really not sure who downvoted, but read the error message:
Field 'user_id' doesn't have a default value (SQL: insert into users ...)
When this error is encountered, the query is trying to insert into the users table, not the profiles one. Since users.user_id doesn't have a default value, nor does it allow null, the error is being thrown. The 3 alternatives above provide a solution to this.
The error has nothing to do with the User or Profile models, as there is an issue with the migration itself.
General error: 1364 Field 'user_id' doesn't have a default value
what this error is saying is that you have a column in the table that you didn't pass
a value for in your form...In your case you didn't pass a value for the field
user_id.I guess what you are trying to implement is that you want to give the primary
key a name.so the fix should be to rename the column $table->bigIncrements('id'); to
$table->bigIncrements('user_id'); and delete the $table->string('user_id');
You can set 'user_id' to allow null from db.
I don't how your relationship is set up but try to make some changes as mentioned below. REMOVE THE use_id from users table. You don't need that column. Or Just rename it to USER_CODE for example make it nullable if it is not a mandatory column $table->string('user_id')->nullable();
To be honest I don't see the purpose of having user_id column in usrs table
// Profiles Migration:
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
...
$table->unsignedInteger('user_id');
....
$table->foreign('user_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
});
}
// Profile.php Model
public function user()
{
return $this->belongsTo('App\User');
}
// User.php Model
public function user()
{
return $this->hasOne('App\Profile');
}
// Inside your Controller
$user = new App\User;
$user->name = 'Darlington Okorie';
$user->email = 'darlingtonokoriec#gmail.com';
$user->password = bcrypt('password');
$user->admin => 1;
if($user->save()) {
$userID = $user->id;
$profile = new App/Profile;
$profile->user_id = $userID;
$profile->avatar = 'uploads/avatar/img.png';
$profile->about = 'Great at writing. Better at blogging';
$profile->facebook = 'facebook.com';
$profile->youtube = 'youtube.com';
$profile->save();
}
Why can't I delete these items from my database, they only have one relationship each, and I'm detaching and deleting each respectively. I have 3 tables Vendor, Brand and Product. The error mentions the Products table but there are no relationships in the Vendor table to the Products table, the relationship is with the Brand table and it's a one to one relationship.
Table structure
Schema::create('vendors', function (Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('image')->nullable();
$table->timestamps();
});
Schema::create('brands', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->nullable();
$table->integer('vendor_id')->unsigned();;
$table->foreign('vendor_id')->references('id')->on('vendors');
$table->timestamps();
});
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('code');
$table->string('sku')->nullable();
$table->text('description_spanish');
$table->text('description_english');
$table->string('image')->nullable();
$table->string('discount');
$table->string('cif')->nullable();
$table->string('color')->nullable();
$table->string('color_ab')->nullable();
$table->integer('brand_id')->unsigned();
$table->timestamps();
$table->foreign('brand_id')->references('id')->on('brands');
});
Vendor Model and relationship
class Vendor extends Model
{
protected $hidden = ['created_at','updated_at'];
public function brands(){
return $this->hasMany(Brand::class);
}
}
Brand Model and relationship
class Brand extends Model
{
public function vendor() {
return $this->belongsTo(Vendor::class);
}
}
Product relationship with Brand
public function brand()
{
return $this->belongsTo(Brand::class);
}
Vendor destroy function
public function destroy($id)
{
DB::beginTransaction();
$vendor = Vendor::findOrFail($id);
$vendor->brands()->delete();
$vendor->delete();
DB::commit();
}
Brand destroy function
public function destroy($id)
{
DB::beginTransaction();
$vendor = Brand::findOrFail($id);
$vendor->vendors()->delete();
$vendor->delete();
DB::commit();
}
Product destroy funcion
public function destroy($id)
{
$product = Product::findOrFail($id);
DB::beginTransaction();
$product->sizes()->detach();
$product->tags()->detach();
$product->fields()->detach();
$product->countries()->detach();
$this->removeProductImage($product);
$product->exportationFactors()->delete();
$product->delete();
DB::commit();
}
when I try to delete a Vendor I recieve this error
SQLSTATE[23000]: Integrity constraint violation:
1451 Cannot delete or update a parent row:
a foreign key constraint fails (`sondel`.`products`,
CONSTRAINT `products_brand_id_foreign`FOREIGN KEY (`brand_id`)
REFERENCES `brands` (`id`)) (SQL: delete from `brands` where
`brands`.`vendor_id` = 2 and `brands`.`vendor_id` is not null)
and when I try to delete a Brand I have basically the same error
SQLSTATE[23000]: Integrity constraint violation:
1451 Cannot delete or update a parent row:
a foreign key constraint fails (`sondel`.`brands`, CONSTRAINT
`brands_vendor_id_foreign` FOREIGN KEY (`vendor_id`)
REFERENCES `vendors` (`id`)) (SQL: delete from `vendors`
where `vendors`.`id` = 2)
I'm not sure what I'm doing wrong.
Error on Vendor Delete is Because You are deleting Vendor's all Brands which are again related to Products So, without deleting their related products you can't delete them.
So, you have to delete products at first. Create a relation of Products on Brand Model
public function products(){
return $this->hasMany(Products::class);
}
Then on Vendor's destroy get its all brands loop through and delete all products.
DB::beginTransaction();
$vendor = Vendor::findOrFail($id);
$vendor->brands->each(function ($brand) {
$brand->products->each(function ($product) {
$product->sizes()->detach();
$product->tags()->detach();
$product->fields()->detach();
$product->countries()->detach();
$this->removeProductImage($product);
$product->exportationFactors()->delete();
$product->delete();
});
});
$vendor->brands()->delete();
$vendor->delete();
DB::commit();
Same On Brand's delete get all its products and delete its products first.
DB::beginTransaction();
$brand = Brand::findOrFail($id);
$brand->products->each(function ($product) {
$product->sizes()->detach();
$product->tags()->detach();
$product->fields()->detach();
$product->countries()->detach();
$this->removeProductImage($product);
$product->exportationFactors()->delete();
$product->delete();
});
$brand->delete();
DB::commit();
I would like to suggest you to use Eloquent's deleting event on all three models then you will not need to care about nested model's foreign key and you will get rid of code repitation. see: https://laravel.com/docs/6.0/eloquent#events
So I am trying to figure a solution to this but not sure exactly how to do this. I have a table that stores all the shows that happen. In a given show I can have multiple providers attend that show. A provider could also attend many shows as well. So how do I store this in the DB and do the eloquent relationship?
Show Schema
Schema::create('shows', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('number')->unsigned();
$table->dateTime('airDate');
$table->string('podcastUrl')->nullable();
$table->timestamps();
});
Provider Schema
Schema::create('providers', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('shortName')->nullable();
$table->string('image')->nullable();
$table->string('social')->nullable();
$table->timestamps();
});
Would I store the provider_id in the shows schema?
Update 1
So I created a new migration for a pivot table
Schema::create('provider_show', function (Blueprint $table) {
$table->integer('provider_id')->unsigned()->index();
$table->foreign('provider_id')->references('id')->on('providers')->onDelete('cascade');
$table->integer('show_id')->unsigned()->index();
$table->foreign('show_id')->references('id')->on('shows')->onDelete('cascade');
$table->primary(['provider_id', 'show_id']);
});
Then in the show model I created the following
public function providers()
{
return $this->belongsToMany(Provider::class);
}
Now when I am saving a new show I added a multiselect to select the providers I want
$show = new Show;
$show->name = $request->name;
$show->number = $request->number;
$show->airDate = $request->airDate;
$show->podcastUrl = $request->podcastUrl;
$show->providers()->attach($request->providerList);
$show->save();
Session::flash('message', "Created Successfully!");
return back();
Then when I save I get the following error
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: provider_show.show_id (SQL: insert into "provider_show" ("provider_id", "show_id") select 1 as "provider_id", as "show_id" union all select 2 as "provider_id", as "show_id")
Create a provider_show migration which will act as your pivot table.
This table would contain both provider_id and show_id which will provide the many-to-many relationship between those entities.
Then on your Provider model you can provide a shows() method which returns a BelongsToMany relationship.
// In your Provider model
public function shows()
{
return $this->belongsToMany('App\Show');
}
Note that Laravel by default looks for a pivot table name based alphabetically on the two relationships.
You can also add the inverse on your Show model by providing a providers() method that also returns a BelongsToMany relationship.
I have 2 models and both they aren't using the ID from the table, but the field internal_id. So i customized my pivot schema but i got stuck on connecting them. Im getting the error:
General error: 1215 Cannot add foreign key constraint (SQL: alter table `seoshop_category_product` add constraint seoshop_category_product_category_id_foreign foreign key
(`category_id`) references `seoshop_categories` (`internal_id`) on delete cascade)
The code for the migration is:
Schema::create('seoshop_category_product', function(Blueprint $table)
{
$table->increments('id');
$table->integer('category_id')->unsigned()->index();
$table->foreign('category_id')->references('internal_id')->on('seoshop_categories')->onDelete('cascade');
$table->integer('product_id')->unsigned()->index();
$table->foreign('product_id')->references('internal_id')->on('seoshop_products')->onDelete('cascade');
$table->timestamps();
});
Both fields as seoshop_products.internal_id as seoshop_categories.internal_id are existing, column types are both int(11).
Can someone tell me what is going wrong?
Migrations for the tables seoshop_categories and seoshop_products
//seoshop_products
public function up()
{
Schema::create('seoshop_products', function(Blueprint $table)
{
$table->increments('id');
$table->integer('shop_id');
$table->integer('internal_id')->signed()->index();
$table->integer('internal_variant_id');
$table->string('visible');
$table->string('tags');
$table->timestamps();
});
}
//Table seoshop_categories
public function up()
{
Schema::create('seoshop_categories', function(Blueprint $table)
{
$table->increments('id');
$table->integer('internal_id')->signed()->index();
$table->datetime('seoshop_created_at');
$table->datetime('seoshop_updated_at');
$table->text('full_description');
$table->timestamps();
});
}
Okay so now i've create my table, and its working as how it should. I need to get my product with categories (many-2-many). So i use
SEOshopProduct::find(1)->with('categories')->get();
After a dd() the categories are empty and i've looked into my query how it is called:
[8] array(3) {
["query"] "select `seoshop_categories`.*, `seoshop_category_product`.`product_id` as `pivot_product_id`, `seoshop_category_product`.`category_id` as `pivot_category_id` from `seoshop_categories` inner join `seoshop_category_product` on `seoshop_categories`.`id` = `seoshop_category_product`.`category_id` where `seoshop_category_product`.`product_id` in (?)"
["bindings"] array(1) {
[0] 8
}
["time"] 0.37
}
The internal_id's of both products and categories is greater then 10.000 and i dont see it back in the query.
My models:
Product:
public function categories(){
return $this->belongsToMany('SEOshopCategory', 'seoshop_category_product', 'product_id', 'category_id');
}
Categories:
public function products(){
return $this->belongsToMany('SEOshopCategory', 'seoshop_category_product', 'category_id', 'product_id');
}
To setup the foreign key constraint, the field definitions need to match exactly. In this case, however, the seoshop_category_product.category_id field is defined as an UNSIGNED INT, but the referenced seoshop_categories.internal_id field is defined as a SIGNED INT. The same is true for the foreign key for your products.
So, you can either update the internal_id fields on your categories and products tables to be unsigned, or you can update your foreign key fields on your pivot table to be signed.
You can tell Laravel what the local and foreign keys are when you define the relationship in your model...
class Product extends Eloquent
{
public function categories() {
return $this->hasMany('Category', 'internal_id', 'id');
}
}
class Category extends Eloquent
{
public function products() {
return $this->hasMany('Product', 'internal_id', 'id');
}
}