According to Dayle Rees
All foreign key columns follow a similar naming convention. The singular form of the related model appended with _id.
Consider this migration:
class CreateTables extends Migration {
// ...
public function up()
{
Schema::create('artists', function($table) {
$table->increments('id');
$table->string('name',64);
$table->timestamps();
});
Schema::create('albums', function($table) {
$table->increments('id');
$table->string('name',64);
$table->integer('artist_id')->unsigned();
$table->foreign('artist_id')->references('id')->on('artists');
$table->timestamps();
});
}
Here are my eloquent models:
<?php
// Artist model
class Artist extends Eloquent {
public function albums() {
return $this->hasMany('Album');
}
}
<?php
// Album model
class Album extends Eloquent {
public function artists() {
return $this->belongsTo('Artist');
}
}
I used them like this:
Route::get('/', function() {
$artist = new Artist;
$artist->name = "Morbid Angel";
$artist->save();
$album = new Album;
$album->name = "Altars of Madness";
$album->artists()->associate($artist);
$album->save();
return View::make('hello');
});
This does not seem to work, according to the logs:
[2015-06-09 06:01:12] production.ERROR: exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'artists_id' in 'field list''
But I did not create a artists_id. What does this mean? Shouldn't laravel find artist_id because it should be singular followed by _id?
This was your problem. You have named your relation artists, but it should be artist. That's why it was looking for a column named artists_id.
You should define your relations as follow as it looks to me it is a One to Many.
In your Artists Model
public function albums()
{
return $this->hasMany('Album');
}
In your Albums Model
public function artist()
{
return $this->belongsTo('Artist');
}
Then try your code.
Route::get('/', function() {
$artist = new Artist;
$artist->name = "Morbid Angel";
$artist->save();
$album = new Album;
$album->name = "Altars of Madness";
$artist->albums()->save($album);
return View::make('hello');
});
In your artist model try return $this->hasMany('Album', 'artist_id');
Related
[SOLVED]I'm facing problems trying to fix the following error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'testimonial_by' in 'field list' (SQL: insert into testimonials (testimonial_by, testimonial_text, updated_at, created_at) values (John Doe, Lorem Ipsum is really lit!, 2019-10-02 20:37:53, 2019-10-02 20:37:53))
I have added my code related to 'testimonials' below.
app/Testimonial.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Testimonial extends Model
{
public $guarded = [];
public function allTestimonials()
{
return self::all();
}
}
TestimonialController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Testimonial;
class TestimonialController extends Controller
{
public function index()
{
$testimonials = Testimonial::all();
return view('dashboard.testimonials.index')->withTestimonials($testimonials);
}
public function create()
{
return view('dashboard.testimonials.create');
}
public function store(Request $request)
{
$request->validate(['testimonial_text'=>'required']);
$testimonial = Testimonial::create($request->all());
if($testimonial)
{
$this->success('Testimonial added successfully');
}
else
{
$this->error();
}
return redirect()->back();
}
public function edit(Testimonial $testimonial)
{
return view('dashboard.testimonials.edit')->withTestimonial($testimonial);
}
public function update(Testimonial $testimonial,Request $request)
{
if($testimonial->update($request->all()))
{
$this->success('Testimonial Updated Successfully');
}
else
{
$this->error();
}
return redirect()->route('dashboard.testimonials.index');
}
public function destroy(Testimonial $testimonial)
{
if($testimonial->delete())
{
$this->success('Testimonial Deleted Successfully');
}
else
{
$this->error();
}
return redirect()->back();
}
}
migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTestimonialsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('testimonials', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('testimonials');
}
}
I can't seem to find where I'm going wrong. Thank you for your time and support.
You need to add those columns to your migration:
Schema::create('testimonials', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('testimonial_by'); // or $table->integer('testimonial_by'); if a user ID
$table->string('testimonial_text');
$table->timestamps();
});
it looks like you have fields with names (testimonial_by and testimonial_text) in the form. But they are absent in migration. Can you open your DB and look at columns?
If they are absent - add to migration
$table->string('testimonial_by'); //or integet
$table->string('testimonial_text');
PS. you may need in the future in model protected $fillable = [array with column names for filling];
Add these lines to your migration..
Schema::create('testimonials', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('testimonial_by',200);
$table->text('testimonial_text');
$table->timestamps();
});
In your model add these fields as fillable
class Testimonial extends Model
{
public $guarded = [];
public $timestamps = true;
protected $fillable = ['testimonial_text','testimonial_by'];
public function allTestimonials()
{
return self::all();
}
}
Create table entry using required fields only..
$testimonial = Testimonial::create(
'testimonial_by' => $request->input('testimonial_by'), //put current user name
'testimonial_text' => $request->input('testimonial_text')
);
Remove the migration file entry from migrations table and run the php artisan:migrate command.It will create testimonials table with updated columns.
Thank you all for your help. I found out where I was going wrong.
I added the following likes to my migrations
$table->string('testimonial_by');
$table->string('testimonial_text');
Then i tried running php artisan migrate but I still got the same error.
So, I went and created the columns on my own and simple ran the project and it worked.
In my application, there will be multiple investors tagged for single purchase entry. So on loading a purchase entry, I should get all the investors associated.
In my controller,
return response()->json(GoldPurchase::with('investors')->get());
Mapping table schema,
Schema::create('gold_purchase_investor', function (Blueprint $table) {
$table->increments('id');
$table->integer('investor_id')->unsigned();
$table->integer('purchase_id')->unsigned();
$table->timestamps();
$table->foreign('investor_id')
->references('id')
->on('investors')
->onDelete('cascade');
$table->foreign('purchase_id')
->references('id')
->on('gold_purchases')
->onDelete('cascade');
});
Purchase model,
class GoldPurchase extends Model
{
public function investors() {
return $this->hasMany('App\GoldPurchaseInvestor');
}
}
Investor model,
class Investor extends Model
{
protected $fillable = ['name', 'address', 'mobile', 'email'];
public function purchases() {
return $this->hasMany('App\GoldPurchase');
}
}
PurchaseInvestor model,
class GoldPurchaseInvestor extends Model
{
protected $table = 'gold_purchase_investor';
public function purchase() {
return $this->belongsTo('App\GoldPurchase');
}
public function investor() {
return $this->belongsTo('App\Investor');
}
}
With this, I am getting error,
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'gold_purchase_investor.gold_purchase_id' in 'where clause' (SQL: select * from `gold_purchase_investor` where `gold_purchase_investor`.`gold_purchase_id` in (1))
You have to specify the custom foreign key:
public function investors() {
return $this->hasMany('App\GoldPurchaseInvestor', 'purchase_id');
}
But this is actually a case for a BelongsToMany relationship:
public function investors() {
return $this->belongsToMany('App\Investor', 'gold_purchase_investor', 'purchase_id');
}
From the Eloquent Relationship:
Remember, Eloquent will automatically determine the proper foreign key column on the Comment model. By convention, Eloquent will take the "snake case" name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Comment model is post_id.
$this->hasMany('App\Comment', 'foreign_key', 'local_key');
So try to write your foreign key and local key in the relationships
In your case I think it would be something like that:
class GoldPurchase extends Model`
{
public function investors() {
return $this->hasMany('App\GoldPurchaseInvestor', 'investor_id', 'id');
}
}
Use belongsToMany for many-to-many relationships.
GoldPurchase.php
class GoldPurchase extends Model{
public function investors() {
return $this->belongsToMany('App\Investor','gold_purchase_investor','purchase_id','investor_id');
}
}
Investor.php
class Investor extends Model{
protected $fillable = ['name', 'address', 'mobile', 'email'];
public function purchases() {
return $this->belongsToMany('App\GoldPurchase','gold_purchase_investor','investor_id','purchase_id');
}
}
You don't need a third model for pivot table at all.
GoldPurchaseInvestor is not at all needed.
I am having issues calling a departure ICAO and arrival ICAO from my schedules table. Laravel keeps giving me errors that my relationships are screwed up. Here is the code.
Schema::create('airports', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('city');
$table->string('country');
$table->string('iata');
$table->string('icao');
$table->double('lat');
$table->double('lon');
$table->longText('data')->nullable(); //JSON Data for All gate information for the system.
$table->softDeletes();
});
Schema::create('schedule_templates', function (Blueprint $table) {
$table->increments('id');
$table->string('code');
$table->string('flightnum');
$table->integer('depicao')->unsigned();
$table->foreign('depicao')->references('id')->on('airports')->onDelete('cascade');
$table->integer('arricao')->unsigned();
$table->foreign('arricao')->references('id')->on('airports')->onDelete('cascade');
$table->string('aircraft')->nullable();
$table->boolean('seasonal');
$table->date('startdate');
$table->date('enddate');
$table->time('deptime');
$table->time('arrtime');
$table->integer('type');
$table->boolean('enabled');
$table->text('defaults');
$table->timestamps();
$table->softDeletes();
});
Here are the Models
class ScheduleTemplate extends Model
{
public $table = "schedule_templates";
public function depicao()
{
return $this->hasOne('App\Models\Airport', 'depicao');
}
public function arricao()
{
return $this->hasOne('App\Models\Airport', 'arricao');
}
}
class Airport extends Model
{
//
public $timestamps = false;
public function schedules()
{
return $this->belongsToMany('App\ScheduleTemplate');
}
}
When I attempt to query using the following code, I get the error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'vaos_airports.depicao' in 'where clause' (SQL: select * from vaos_airports where vaos_airports.depicao in (1))
$schedules = ScheduleTemplate::with('depicao')->with('arricao')->get();
The end goal is to pull the results into a table. Here is that code if interested.
#foreach($schedules as $s)
<tr>
<td>{{$s->code}}</td>
<td>{{$s->flightnum}}</td>
<td>{{$s->depicao()->name}}</td>
<td>{{$s->arricao()->name}}</td>
<td>{{$s->aircraft}}</td>
<td>{{$s->seasonal}}</td>
<td>{{$s->type}}</td>
</tr>
#endforeach
EDIT:
I fixed the relationship problem Apparently I had them swapped. Here are the updated Model classes
class ScheduleTemplate extends Model
{
public $table = "schedule_templates";
public function depicao()
{
return $this->belongsTo('App\Models\Airport', 'depicao');
}
public function arricao()
{
return $this->belongsTo('App\Models\Airport', 'arricao');
}
}
class Airport extends Model
{
//
public $timestamps = false;
public function schedules()
{
return $this->hasMany('App\ScheduleTemplate');
}
}
The error now lies in the view file. I will either get a BelongsTo error:
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name
or this if I have arricao or depicao without "()"
Trying to get property of non-object
The point is, that the second argument of a relationship should be the foreign key, and the second the local key.
From the docs:
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
So in your case, try this:
public function depicao()
{
return $this->hasOne('App\Models\Airport', 'id', 'depicao');
}
public function arricao()
{
return $this->hasOne('App\Models\Airport', 'id', 'arricao');
}
Update
The errors are thrown because you have the same column name for this relationship. In my opinion, two solutions:
Try to get the first object out of the relationship, like this. But note here: eager loading will not work!
<td>{{$s->depicao()->first()->name}}</td>
<td>{{$s->arricao()->first()->name}}</td>
Rename your relationships or the columns, so they don't overlap current column names. This is by far the best option.
For example, you could change the columns to depeciao_id and arricao_id, this also indicates that the columns are referenced to another table with corresponding ID, which is more descriptive.
There is something I miss in the eloquent one-to-one relationship:
class MeetingTest extends Model
{
protected $table = 'meeting_tests';
public function meeting() {
return $this->belongsTo('App\Meeting','meeting_id','id');
}
public function observation() {
return $this->hasOne('App\Observation','meeting_test_id','id');
}
public function activity() {
return $this->hasOne('App\TestActivity','activity_id','id');
}
}
The Observation Class is
class Observation extends Model
{
protected $table = 'observations';
public function meetingTest() {
return $this->belongsTo('App\MeetingTest','meeting_test_id','id');
}
}
If I run php artisan tinker and
$mtn = App\MeetingTest::create();
$mtn->save();
$ob = App\Observation::create();
$ob->save;
$mtn->observation()->save($ob);
At this point inside the Observation record I can see the meeting_test_id filled with the correct id of the meetingTest, but if I try:
$mtn->observation
it gives me null; and in the Database there is no observation ID in the observation_id field;
this is the migration:
Schema::create('meeting_tests', function (Blueprint $table) {
$table->increments('id');
$table->integer('meeting_id')->unsigned();
$table->integer('observation_id')->unsigned()->nullable();
$table->integer('activity_id')->unsigned()->nullable();
$table->timestamps();
});
I don't understand what is not correct.
I can see observation_id and activity_id in your meeting_tests table, which makes records in this table the owned side of one-to-one/one-to-many relation. Therefore, both activity and observation relations in MeetingTest should return $this->belongsTo instead of $this->hasOne
I have Member and SkyMedRep models:
class SkyMedRep extends Model
{
protected $fillable = [
'id','rep_id',
];
public function members()
{
return $this->hasMany('App\Member');
}
}
class Member extends User
{
public function sky_med_rep()
{
return $this->belongsTo('App\SkyMedRep');
}
}
This is migration for Member:
public function up()
{
Schema::create('members', function (Blueprint $table) {
$table->increments('id');
$table->integer('sky_med_rep_id')->unsigned();
$table->timestamps();
});
Schema::table('members', function($table) {
$table->foreign('sky_med_rep_id')->references('id')- >on('sky_med_reps')->nullable(true);
});
}
Member model contains foreign key referencing SkyMedRep model.After defining such relationship, I am trying to assign object of SkyMedRep model to the object of Member model like:
$member->sky_med_rep = $sky_med_rep;
Here, $member is the object of Member model and $sky_med_rep is the object of SkyMedRep model.
When I try $member->save(), I am getting error "Unknown column 'sky_med_rep' in field list". It seems that sky_med_rep is not being able to treat as foreign key reference. Below is my code to save the data:
$member = new Member();
$member->sky_med_member_number = $request->input("sky_med_member")['member_number'];
$sky_med_rep = SkyMedRep::firstOrNew(['rep_id' => $request->input("sky_med_member")['rep_id']]);
$sky_med_rep->name = $request->input("sky_med_member")['name'];
$sky_med_rep->save();
$member->sky_med_rep = $sky_med_rep;
$member->save();
Instead of $member->sky_med_rep = $sky_med_rep; You should write $member->sky_med_rep->associate($sky_med_rep);.
Also have a look at http://www.php-fig.org/psr/psr-2/ coding style guide. Method names should be camelCase, not underscore.