One to many relationship Laravel migration - laravel

I currently have a 1:1 relationship and I need it to be a one to many.
Such that Job Details can have multiple results for 1 Job Search.
Job Searches
public function up()
{
Schema::create('job_searches', function (Blueprint $table) {
$table->increments('id');
});
}
Job Details
public function up()
{
Schema::create('job_details', function (Blueprint $table) {
$table->integer('job_details_id',11);
$table->foreign('job_details_id')->references('id')->on('job_searches');
});
}
The current output I am getting is:
Job_Search_Id
1
Job_Detail_Id
1
When adding another result to the job details I get:
Illuminate\Database\QueryException with message 'SQLSTATE[23503]:
Foreign key violation: 7 ERROR: insert or update on table
"job_details" violates foreign key constraint
"job_details_job_details_id_foreign"
I also have stated the relationships in my models
Job Search Model
class JobSearches extends Model
{
protected $primaryKey = 'id';
public function job_details(){
return $this->belongsToMany('App\job_details');
}
}
Job Details Model
class JobDetails extends Model
{
protected $primaryKey = 'job_details_id';
public function job_search(){
return $this->hasOne('App\job_search');
}

Change the migration to:
public function up()
{
Schema::create('job_details', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('job_search_id');
});
Schema::table('job_details', function (Blueprint $table) {
$table->foreign('job_search_id')->references('id')->on('job_searches');
});
}
And the JobSearch class:
class JobSearch extends Model
{
public function jobDetails(){
return $this->hasMany('App\JobDetail');
}
}
And the JobDetail class:
class JobDetails extends Model
{
public function jobSearch()
{
return $this->belongsTo('App\JobSearch');
}
}
If you'll use the code without modification, it will work for you.

Related

Laravel 8 pivot working only in 1 direction

I got a problem I have done model and migration for 3 tables: movies, actors and actor_movie (pivot)
when Im using from model Actor method movie() it working but don't work from Movie using actor()
class Movie extends Model
{
use HasFactory;
public function actors()
{
return $this->belongsToMany(Actor::class, 'actor_movie');
}
}
class Actor extends Model
{
use HasFactory;
public function movies()
{
return $this->belongsToMany(Movie::class, 'actor_movie');
}
}
movies migration:
public function up()
{
Schema::create('movies', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
actor migration:
public function up()
{
Schema::create('actors', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
Pivot migration:
public function up()
{
Schema::create('actor_movie', function (Blueprint $table) {
$table->bigInteger('movie_id')->unsigned()->index();
$table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
$table->bigInteger('actor_id')->unsigned()->index();
$table->foreign('actor_id')->references('id')->on('actors')->onDelete('cascade');
$table->primary(['actor_id', 'movie_id']);
$table->timestamps();
});
}
As said in the comments, you are running your tests in a Tinker console.
Tinker console loads all your PHP files and dependencies on startup and keep them in memory.
For your code to be refreshed, you need to kill tinker and restart it

Laravel: cannot insert into many to many relationship

i hope you're having a good day.
so i have this ManyToMany relationship where a user can apply to multiple jobs, and a job can have multiple applicants (users).
here is the table schema
Schema::create('applicant_job', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('job_id');
$table->unsignedBigInteger('applicant_id');
$table->unique(['job_id', 'applicant_id']);
$table->foreign('job_id')
->references('id')
->on('jobs')
->onDelete('cascade');
$table->foreign('applicant_id')
->references('id')
->on('default_users')
->onDelete('cascade');
});
and here is the model code.
DefaultUser.php
class DefaultUser extends Model
{
public function user()
{
return $this->morphOne(User::class, 'userable');
}
public function applications()
{
return $this->belongsToMany(Job::class, 'applicant_job', 'job_id', 'applicant_id');
}
}
and Job.php
class Job extends Model
{
public function owner()
{
return $this->belongsTo(BusinessUser::class, 'business_user_id');
}
public function applicants()
{
return $this->belongsToMany(DefaultUser::class, 'applicant_job', 'applicant_id', 'job_id');
}
}
everything seems ok and find, however when i try to save ( a user applying to a job), i get the following error
i'm doing so inside ApplyToJobController.php
class ApplyToJobController extends Controller
{
public function store(Job $job, Request $request) {
$default_user = auth()->user()->userable;
$job->applicants()->attach($default_user->id);
return redirect("/en");
}
}
and, Thank you very much for your answers.
EDIT
i have changed the column names to this
Schema::create('applicant_job', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('job_id');
$table->unsignedBigInteger('default_user_id');
$table->unique(['job_id', 'default_user_id']);
$table->foreign('job_id')
->references('id')
->on('jobs')
->onDelete('cascade');
$table->foreign('default_user_id')
->references('id')
->on('default_users')
->onDelete('cascade');
});
it made it work, im curios any idea why?
Try to switch the order of the foreign keys in the applicants relation declared in the Job model like the example below :
public function applicants()
{
return $this->belongsToMany(DefaultUser::class, 'applicant_job', 'job_id', 'applicant_id');
}

Why does Laravel Combine query is not working?

My Channels Model is :
class Channels extends Model
{
protected $fillable = ['title','slug'];
public function Discussion()
{
return $this->hasMany('App\Discussion');
}
}
Channel Model is:
class Channels extends Model
{
protected $fillable = ['title','slug'];
public function Discussion()
{
return $this->hasMany('App\Discussion');
}
}
Channel Migration File :
class CreateChannelsTable extends Migration
{
public function up()
{
Schema::create('channels', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('slug');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('channels');
}
}
Discusion Migraion file
class CreateDiscussionsTable extends Migration
{
public function up()
{
Schema::create('discussions', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('channel_id')->unsigned();
$table->string('title');
$table->text('content');
$table->text('slug');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('discussions');
}
}
**Controller is: **
class HomeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function channel($slug)
{
$channel= Channels::where('slug',$slug)->first();
return view('channel')->with('discussion',$channel->Discussions);
}
}
And Finnaly the route is
Route::get('channel/{slug}',[
'uses' => 'HomeController#channel',
'as' => 'channel']);
**Now i am trying to fetch the data: **
$channel->Discussions
but it's giving me the error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'discussions.channels_id' in 'where clause' (SQL: select * from discussions where discussions.channels_id = 1 and discussions.channels_id is not null)
I don't know what exactly to do now. Please Help me
First of all, it's very important to name your classes and its relationships appropriately.
Laravel makes some assumptions about your foreign keys based on your class names and relationship definitions. You could also specify the foreign keys if you want.
However, here's how i'd do it.
class Channel extends Model
{
protected $fillable = ['title','slug'];
public function discussions()
{
return $this->hasMany('App\Discussion');
}
}
Notice here the model name is called Channel. When we have this class name and relationship, Laravel will assume that the discussion model has a foreign key called channel_id which it does.
You also need to define an inverse relationship in your Discussion model
class Discussion extends Model
{
public function channel()
{
return $this->belongsTo('App\Channel');
}
}
Now, doing the following would work:
public function channel($slug)
{
$channel = Channel::whereSlug($slug)->first();
return view('channel')->with('discussion', $channel->discussions);
}
If you are tied and cannot change the model name for whatever reason, then you need to specify a foreign key on your relationship definitions.
For example:
public function discussions()
{
return $this->hasMany('App\Discussion', 'channel_id');
}
public function channel()
{
// This one can stay the same as Laravel will try to match `channel_id`
// on the discussion table to the id on the channels table
return $this->belongsTo('App\Channel');
}
Fore more information, read about Eloquent Relationships.
Sorry, I was already writing this up when #Julien Metral commented, but this is an extension of what he already said :)

Laravel Relations, Models and Migrations

I have a problem with my relations in laravel:
I have two tables, Languages and Customers.The customer just can have 1 language. These are my migrations and Models:
Migrations:
Schema::create('tbl_customers', function (Blueprint $table){
$table->increments('id');
$table->string('first_name',255);
$table->string('last_name',255);
$table->date('date_of_birth');
$table->string('email',255);
$table->string('phone_number',255);
$table->string('phone_number2',255);
$table->string('password', 255);
$table->unsignedInteger('dealer_id');
$table->string('picture_profile',255);
$table->string('occupation',255);;
//Foreign key
$table->unsignedInteger('language_id');
$table->string('about_me',255);
});
Schema::create('tbl_languages', function (Blueprint $table){
$table->increments('id');
$table->string('language',255);
});
This is the foreign Key:
Schema::table('tbl_customers', function (Blueprint $table){
$table->foreign('language_id')->references('id')
->on('tbl_languages')->onDelete('cascade');
});
These are my Models.
Customer:
class Customer extends Model{
protected $table='tbl_customers';
protected $primaryKey="id";
protected $fillable=['address_id','first_name','last_name','gender_id','date_of_birth','email','phone_number','phone_number2',
'dealer_id','picture_profile','occupation','time_zone_id','language_id','about_me'];
protected $hidden=['password'];
public $timestamps = false;
public function language(){
return $this->hasMany(Language::class);
}}
Language
class Language extends Model{
protected $table='tbl_languages';
protected $primaryKey="id";
protected $fillable=['language'];
public $timestamps=false;
public function customers(){
return $this->belongsToMany(Customer::class);
}}
So, If I make a query I have the next error:
error
why? If the migrations have the standard that Laravel says
If I change the Customer model like this:
public function language(){
return $this->hasMany(Language::class,'id','language_id');
}
It works good, but Languages no.
I wish you guys can help me.
add this to your Customer model:
public function language(){
return $this->belongsTo('App\Language');
}
and this to your Language model:
public function customers(){
return $this->hasMany('App\Customer');
}

One to many relationship returns NULL

I have the following Migrations:
Table: bebidas:
class CreateBebidasTable extends Migration{
public function up() {
Schema::create('bebidas', function ($table) {
$table->increments('id');
$table->integer('tipo_id')->unsigned();
$table->string('bebi_name');
$table->string('bebi_size');
$table->float('bebi_price');
$table->timestamps();
$table->foreign('tipo_id')->references('id')->on('tipobebidas');
});
}
public function down() {
Schema::drop('bebidas');
}
}
Table: tipobebidas
class CreateTiposBebidasTable extends Migration {
public function up()
{
Schema::create('tipobebidas', function($table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
public function down()
{
Schema::drop('tipobebidas');
}
}
These are the models:
class Bebida extends Eloquent{
public function TipoBebida() {
return $this->belongsTo('TipoBebida');
}
}
class TipoBebida extends Eloquent{
protected $table = "tipobebidas";
public function Bebidas() {
return $this->hasMany('Bebida');
}
}
Each Bebida (drink) has a TipoBebida (drink type) and vive-versa. I'm trying to get a composed table showing all fields from the bebidas table and tipobebidas table.
Based on Laravel's documentation on eager loading, I'm running the following command:
$bebidas = Bebida::with('tipobebida')->get();
At this point $bebidas has the following value: (I'm removing the timestamps fields)
[
{"id":1,"bebi_name":"COCA-COLA","bebi_size":"1 litro",
"bebi_price":4,"tipo_id":1,"tipobebida":null},
{"id":2,"bebi_name":"COCA ZERO","bebi_size":"1 litro",
"bebi_price":4,"tipo_id":1,"tipobebida":null}
]
Instead of "tipobebida":null, I was expecting something like "name":"refrigerantes" or some representation of the tipobebidas table contents.
I inspected the SQL commands being run, here it is:
select * from `tipobebidas` where `tipobebidas`.`id` in (?)
How can I get this to work?
I'll be using this data on a couple nested foreach loops to show the drinks Bebida grouped by type TipoBebida.
Thank you!
I got it to work. It all came down to naming conventions.
Here's what I did:
-The name of the foreign id field must be the singular of the table name plus _id, therefore the migration for bebidas was changed to the following:
class CreateBebidasTable extends Migration{
public function up() {
Schema::create('bebidas', function ($table) {
$table->increments('id');
$table->integer('tipobebida_id')->unsigned(); // ** new field name **
$table->string('name');
$table->string('size');
$table->float('price');
$table->timestamps();
});
}
public function down() {
Schema::drop('bebidas');
}
}
Also, the foreign key relationship was producing a SQL error, tried to fix it, still nothing, so I removed the following line: $table->foreign('tipo_id')->references('id')->on('tipobebidas');
Everything else remained unaltered.
The eager loading is working.
Thanks everyone for your help!!!
First, in tables bebidas and tipobebidas I don't see and foreign keys...
I think in bebidas you should have tipobebidas_id and it is a foreign key to tipobebidas id field.
After you do that, change your model methods to:
class Bebida extends Eloquent{
protected $table = "bebidas";
public function TipoBebida() {
return $this->belongsTo('TipoBebida', 'tipobebida_id');
}
}
class TipoBebida extends Eloquent{
protected $table = "tipobebidas";
public function Bebidas() {
return $this->hasMany('Bebida');
}

Resources