Eloquent foreign key - mysql

I am trying to make a 3 models relationship in Laravel 6 and Foreign keys won't work, becouse i get this error:
Illuminate/Database/QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'products.product_id' in 'where clause' (SQL: select * from `products` where `products`.`product_id` = 1 and `products`.`product_id` is not null limit 1)'
I have a 3 table (the tables are: users, cartItems, products) relationship . The foreign key that refers user's id into cartItems seamns to work, but the one that refers product's id into cartItems don't .
The cartItems table migration:
Schema::create('cart_items', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('product_id');
$table->timestamps();
$table->foreign('product_id')->references('id')->on('products');
});
The products table migraton:
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('productName');
$table->text('description');
$table->integer('price');
$table->string('image');
$table->timestamps();
});
The cartItem model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class cartItem extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
public function product() {
return $this->hasOne(Product::class, 'product_id');
}
}
The product model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $guarded = [];
public function cartItem() {
return $this->belongsToMany(Product::class);
}
}
The user model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use 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',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function cartItems() {
return $this->hasMany(cartItem::class);
}
}

$table->foreign('product_id')->references('id')->on('products');
expects the products table to be created already. Migrations run in filename order, so make sure your products table migration has an earlier "date" stamp than the cart_items table migration.

If you are specifying xxxxx_id columns in the cartItems table, then cartItem is the child model, not the parent. Otherwise you might need to rethink your relationships.
To fix as-is (and leave the migration the same), change your Eloquent relationships to:
// Product.php
public function cartItems() {
return $this->hasMany(cartItem::class);
}
and its inverse:
// cartItem.php
public function product() {
return $this->belongsTo(Product::class);
}

Related

Laravel Eloquent trying to retreive all answers with the same foreign key in a table

I have a project in which I have 3 tables a questions table an answers table and a users table
In the Questions table I have the following:
Schema::create('questions', function (Blueprint $table) {
$table->id();
$table->string('question');
$table->timestamps();
});
In the Users table I have the following:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('district')->nullable();
$table->string('area')->nullable();
$table->string('committee')->nullable();
$table->string('position')->nullable();
$table->rememberToken();
$table->timestamps();
});
In the Answers table I have the following:
Schema::create('answers', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->unsignedBigInteger('question_id');
$table->foreign('question_id')->references('id')->on('questions');
$table->string('answer');
$table->timestamps();
});
And those are the models
class Answer extends Model
{
public function user(){
return $this->hasOne('App\User');
}
public function question(){
return $this->hasOne('App\Question');
}
}
class Question extends Model
{
public function answer(){
return $this->hasMany('App\Answer');
}
}
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','district','area','committee','position',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function answer(){
return $this->hasMany('App\Answer');
}
}
Based on my structure the answers table will have entries with each row made of the user_id and his answer to one question and in the following row the other question
How can I retrieve the data in a table where it shows me in the first row the user in a column with all 4 of his answers in the following 4 columns?
First Answer model should be like this. As it's one-to-many.
class Answer extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
public function question(){
return $this->belongsTo('App\Question');
}
}
And then you can get data like this:
$results = User::with('answer')->first();
// this should give the first `user` with all the answers that belongs to the user.
$results = User::with('answer')->get();
// this should give you all the users.
let's say you need all users and all the answers.
foreach ($results as $user) {
echo $user->name;
foreach ($user->answer as $value) {
echo $value->answer;
}
}
Let me know if it helps.

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'dream.category_course' doesn't exist

I am getting this error in saving a many-to many relation in laravel eloquent.
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'dream.category_course' doesn't exist (SQL: insert into category_course (category_id, course_id, created_at, updated_at) values (5, 6, 2020-07-05 07:48:06, 2020-07-05 07:48:06))
but the table 'category_course' exists in the database dream..
Here is my category model...
class Category extends Model
{
protected $table = 'categories';
protected $guarded = [];
public function Course()
{
return $this->belongsToMany(Course::class)->using(Category_Course::class)->withTimestamps();
}
and this my course model
class Course extends Model
{
protected $table = 'courses';
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function category()
{
return $this->belongsToMany(Category::class)->using(Category_Course::class)->withTimestamps();
}
public function course_content()
{
return $this->hasMany(Course_Content::class);
}
and the customize pivot table
class CreateCategoryCourseTable extends Migration
{
public function up()
{
Schema::create('category__course', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('category_id');
$table->unsignedBigInteger('course_id');
$table->timestamps();
});
}
and here is the controller
public function store(Request $request)
{
$data = $request->validate([
'category_id' => 'required',
'title' => 'required|max:20|min:10',
'description' => 'required|min:30|max:100',
'fee' => 'required|integer|min:1500',
'duration' => 'required|integer|between:1,12'
]);
$category_id = $data['category_id'];
unset($data['category_id']);
$user_id = auth()->user()->id;
$course = \App\user::find($user_id)->course()->create($data);
$course->category()->attach($category_id);
return back();
}
I tried everything.I got but still getting this error....
Anyone have any idea..... please
Two underscores in table name
Schema::create('category__course', function (Blueprint $table)

What is the best way to add dummy data into the "join table" in laravel?

I have two models with many to many relationship, and I did join them with a model with a third table.
What is the best way to insert dummy data into the third table without getting sql error for breaking constraints about foreign key chicks?
Is there a way to use the same data that already exists within the the first two tables?
I have these two tables:
class CreateLessonsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('Lessons', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('title', 100);
$table->text('body');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Lessons');
}
}
The second:
class CreateTagsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name', 50);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('tags');
}
}
and the "join" third table:
class CreateLessonTagsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('lesson_tags', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('lesson_id');
$table->unsignedBigInteger('tag_id');
$table->foreign('lesson_id')->references('id')->on('lessons')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('lesson_tags');
}
}
Thanks in advance
In the simple way
for($i =0;$i<100 ; $i++)
{
DB::table('lesson_tags')->insert(
[
'lesson_id' => Arr::random(DB::table('Lessons')->pluck('id')->toArray()),
'tag_id' => Arr::random(DB::table('tags')->pluck('id')->toArray())
]
);
}
You can use eloquent ORM like this
first you need to declare a relation in tag and lesson Models:
in Tag Model
public function lessons()
{
return $this->belongsToMany('App\Lesson');
}
in Lesson Model
public function tags()
{
return $this->belongsToMany('App\Tag');
}
then you can use this in loop for example
$Lesson = new Lesson();
$Lesson->user_id = ....
...
$Lessons->save();
$tag = new Tag();
$tag->name ='';
$Lessons->tags()->save($tag)
Efficiently, with three queries only:
$lessonIds = Lesson::pluck('id')->toArray();
$tagIds = Tag::pluck('id')->toArray();
$insert = [];
$relationsAmount = 10;
$now = \Carbon\Carbon::now();
for ($i = 0; $i < $relationsAmount; $i++) {
$insert[] = [
'lesson_id' => array_rand($lessonIds),
'tag_id' => array_rand($tagIds),
'created_at' => $now,
'updated_at' => $now,
];
}
\DB::table('lesson_tags')->insert($insert);
// if you name your pivot table per Eloquent naming convention (which would be 'lesson_tag' in this case), Laravel will do lot of things for you out of the box

Eloquent queries wrong table in many-to-many relationship

I'm having trouble with a many-to-many relationshop. When querying the relationship (tested in tinker) I'm getting an error message triggered by sql showing me a query on the wrong table.
My models:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Slideshow extends Model
{
public function pictures ()
{
return $this->hasMany(Picture::class);
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Picture extends Model
{
public function slideshows ()
{
return $this->belongsToMany(Slideshow::class,'slideshowpictures')->withPivot('order')->withTimestamps();
}
}
My migration for this relationship:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSlideshowpicturesMigration extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up ()
{
$tablename = 'slideshowpictures';
Schema::create($tablename, function (Blueprint $table)
{
$table->integer('slideshow_id')->unsigned();
$table->integer('picture_id')->unsigned();
$table->integer('order')->unsigned();
$table->timestamps();
});
Schema::table($tablename, function ($table)
{
$table->foreign('slideshow_id')->references('id')->on('slideshows')->onDelete('cascade');
$table->foreign('picture_id')->references('id')->on('pictures')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down ()
{
Schema::dropIfExists('slideshowpictures');
}
}
Now in tinker I get the following error:
>>> $slide =Slideshow::all()->first();
=> App\Slideshow {#751
id: 1,
name: "1",
occasion_id: 1,
created_at: "2017-09-16 19:01:59",
updated_at: "2017-09-16 19:01:59",
}
>>> $slide->pictures()->exists();
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pictures.slideshow_id' in 'where clause' (SQL: select exists(select * from `pictures` where `pictures`.`slideshow_id` = 1 and `pictures`.`slideshow_id` is not null) as `exists`)'
>>> $slide->pictures();
=> Illuminate\Database\Eloquent\Relations\HasMany {#830}
I could not yet find an answer and hope you can help me figure out why it is selecting from my pictures table and not the junction table which I created.

Laravel 5 - Eloquent relationship returning an empty collection

I'm having trouble with a Laravel 5 relationship. I have 2 models Crew and Event with the corresponding tables crews and events. Crews have many events, and events have one crew. I set up my models and migration as follows:
Schema:
//Crews
Schema::connection('scheduling')->create('crews', function ($table) {
$table->increments('id');
$table->text('name');
$table->boolean('solo');
$table->boolean('active');
$table->text('phone');
});
//Events
Schema::connection('scheduling')->create('events', function ($table) {
$table->increments('id');
// ...
$table->integer('crew_id')->unsigned();
$table->foreign('crew_id')->references('id')->on('crews');
$table->text('notes');
// ...
$table->timestamps();
});
Models:
namespace App\Models\Scheduling;
use Illuminate\Database\Eloquent\Model;
class Crew extends Model {
public $connection = "scheduling";
public $table = "crews";
public function events() {
return $this->hasMany('App\Models\Scheduling\Event', 'id', 'crew_id');
}
public static function active() {
return Crew::where('active', 1)->get();
}
}
namespace App\Models\Scheduling;
use Illuminate\Database\Eloquent\Model;
class Event extends Model {
public $connection = "scheduling";
public $table = "events";
public function crew() {
return $this->belongsTo('App\Models\Scheduling\Crew', 'crew_id', 'id');
}
}
If I run Crew::find(102)->events; I end up with an empty collection.
If I run Events::where('crew_id', 102)->get(); I end up with the list of events I expected.
Any idea what I'm doing wrong here?
Your definition of events relation is invalid - you pass the arguments in wrong order.
Replace:
return $this->hasMany('App\Models\Scheduling\Event', 'id', 'crew_id');
with
return $this->hasMany('App\Models\Scheduling\Event', 'crew_id', 'id');
or simply
return $this->hasMany('App\Models\Scheduling\Event');
as you are using the default values for the column names, so no need to pass them to the relation definition.