Laravel Eloquent Relationship column not found - php

Can you help me with this one?
ANSWER MODEL
class Answer extends Eloquent {
protected $primaryKey = 'ID';
protected $table = 'answers';
protected $fillable = array('customerID', 'agentID', 'status', 'date', 'urn_code', 'urn_id');
public function customer(){
return $this->hasOne('Customer');
}
}
CUSTOMER MODEL
class Customer extends Eloquent {
protected $connection = 'mysql';
protected $table = 'leads';
protected $primaryKey = 'cID';
protected $fillable = array('cID','title', 'first_name','last_name','address1', 'address2', 'post_code','city','phone_number');
public function answers() {
return $this->hasMany('Answer');
}
}
ROUTE
Route::get('sales', function(){
$sales = Customer::with('answers')->get()->paginate(15);
foreach($sales as $sale)
echo $sale->last_name . '<br />';
});
and this is my error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'answers.customer_id'

It's exactly how the error says. In your answers table, Laravel is looking for a customer_id column automatically, and it doesn't exist in this case.
If your customer ID column is under a different name, you can specify it as the second parameter in the hasMany() method:
public function answers() {
return $this->hasMany('Answer', 'my_column');
}
Also, you should probably be using a belongsTo relationship here, as pointed out by #razor.

Since you are using custom primary keys, you need to specify the local key and the foreign key.
public function answers() {
return $this->hasMany('Answer', 'foreign_key', 'local_key');
}
Probably you'll have to update your Answer model as well (please, check out if you really need a hasOne or a belongsTo relation):
public function customer(){
return $this->belongsTo('Customer', 'foreign_key', 'local_key');
}
You can find more info here.

Related

Eloquent Many to Many attach() is passing a null model ID

I am developing an application using Laravel and Eloquent ORM, it uses a database filled with event information.
I have successfully implemented attach() in the relevant controllers for both my user and role models.
My Event model can have many Links. A Link can have Many events.
My problem is that the attach() is not supplying the ID of the object it is being called on, instead it supplies null and I receive the following error message:
SQLSTATE[23000]: Integrity constraint violation:
1048 Column 'link_id'
cannot be null (SQL: insert into 'event_link' ('created_at', 'event_id',
'link_id', 'updated_at') values (2018-06-09 11:27:15, 2, , 2018-06-09 11:27:15))
I've triple checked my models and database structure.
I can't even imagine how this error could occur since the id lacking in the SQL query is the id of the object that the attach() method is actually being called on. If I use sync($eventID, false) instead of attach(), the result is the same.
Event table:
Link table:
Event_Link table:
The following is the problematic method in the controller responsible for storing the record and creating an entry in the event_link weak entity.
The $link object is created successfully if the attach() line is commented out, a JSON representation of a link is returned which confirms this (but it lacks the 'id' field).
public function store(StoreLink $request) {
$link = Link::create([
'title' => $request->title,
'url' => $request->url,
]);
if ($request['eventId']) {
// $request->eventId is passed successfully, $link id is not passed.
$link->events()->attach($request->eventId);
}
return response()->json($link, 201);
}
Link Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Link extends Model
{
protected $table = 'links';
public $incrementing = false;
public $timestamps = true;
protected $primaryKey = "id";
protected $fillable = ['title', 'url'];
public function events()
{
return $this->belongsToMany('App\Event')->withTimestamps();
}
}
Event Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
protected $table = 'events';
public $incrementing = false;
public $timestamps = true;
protected $primaryKey = "id";
protected $fillable = ['description', 'date', 'image', 'category_id'];
public function category()
{
return $this->belongsTo('App\Event', 'category_id');
}
public function links()
{
return $this->belongsToMany('App\Link', 'event_link')->withTimestamps();
}
public function history()
{
return $this->belongsToMany('App\User', 'user_history');
}
public function favourites()
{
return $this->belongsToMany('App\User', 'user_favourites');
}
}
The problem is public $incrementing = false;: Remove the line from both your models.
Your id columns are defined as AUTO_INCREMENT, so $incrementing has to be true.

Laravel Multiple linking column in another table with relationships?

I'm trying to create a league table in Laravel but I'm running into some issues with guess what, relationships, again. They never seem to work for me in Laravel. It's like they hate me.
I have a modal for matches
<?php
namespace App\Database;
use Illuminate\Database\Eloquent\Model;
class Match extends Model
{
protected $primaryKey = 'id';
protected $table = 'matches';
public $timestamps = false;
protected $guarded = ['id'];
}
And a modal for teams, but with a matches() function
<?php
namespace App\Database;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
protected $primaryKey = 'id';
protected $table = 'teams';
public $timestamps = false;
protected $guarded = ['id'];
public function matches() {
return $this->hasMany('App\Database\Match', 'team_one_id, team_two_id');
}
}
I think the issue comes with team_one_id, team_two_id as the teams primary key could be in either one of them columns for the other table. When calling count() on matches() it throws an error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'matches.team_one_id, team_two_id' in 'where clause' (SQL: select count(*) as aggregate from matches where matches.team_one_id, team_two_id = 1 and matches.team_one_id, team_two_id is not null)
can you try this syntax
return $this->hasMany('modelPath', 'foreign_key', 'local_key');
Does Match table have a column maned 'team_id'?
because it's the default naming convention in the laravel docs for mapping the tables.
if you do have the column and populate the data you can just remove the foreign & local keys from matches() relationship. you don't need it. Laravel will automatically map it for you.
if you do not have the 'team_id' on Matches table please add the column and add the respective team ids for matches.
<?php
namespace App\Database;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
protected $primaryKey = 'id';
protected $table = 'teams';
public $timestamps = false;
protected $guarded = ['id'];
public function matches() {
return $this->hasMany('App\Database\Match');
}
}
This way you can implement it, Add these relationship and a method in Team Model
public function homeMatches() {
return $this->hasMany('App\Database\Match', 'team_one_id');
}
public function awayMatches() {
return $this->hasMany('App\Database\Match', 'team_two_id');
}
public function matches() {
return $this->homeMatches->merge($this->awayMatches);
}
Now Fetch the data
$team = Team::find(1);
$matches = $team->matches(); //now it will fetch all matches for both columns
If you want to fetch matches as attributes then you can add one method
in your Team model
public function getMatchesAttribute()
{
return $this->homeMatches->merge($this->awayMatches);
}
Now you can fetch the matches as $matches = $team->matches;
Here is the difference
$team->matches returns Illuminate\Database\Eloquent\Collection
And
$team->matches() returns Illuminate\Database\Eloquent\Relations\{Relation Name}
You can't use matches in Eager loading like Team::with('matches') because matches is not a relationship and that causing your Error. What you can do is add homeMatches and awayMatches in eager loading and then call $team->matches().
$teams = Team::with('homeMatches', 'awayMatches')->get();
$teams->each(function ($team) {
print_r($team);
print_r($team->matches());
});

Laravel 5.6.5 relationship executing wrong query

As you can see on the following image my laravel relation between shoporder and shoporderroutingstepplans is not as it has to be.
I have no idea what I exactly did wrong so I hope someone can help me out. In the code beneath I have left some fields out of the code to make it more legible.
class shoporder extends Model
{
protected $primaryKey = 'ID';
protected $fillable = [
'CADDrawingURL',
'ID',
'Costcenter',
'CostcenterDescription',
'Costunit',
'CostunitDescription',
'Created',
'Creator',
'CreatorFullName',
'Description',
'ShopOrderParent',
'ShopOrderParentNumber',
'ShopOrderRoutingStepPlanCount',
'Status',
'SubShopOrderCount',
];
public function shopOrderRoutingStepPlans() {
return $this->hasMany('App\shopOrderRoutingStepPlan', 'ShopOrder', 'ID');
}
}
class ShopOrderRoutingStepPlan extends Model
{
protected $primaryKey = 'ID';
public $table = "shoporderroutingstepplans";
protected $fillable = [
'Account',
'ID',
'AccountName',
'AccountNumber',
'AttendedPercentage',
'Backflush',
'Created',
'Creator',
'CreatorFullName',
'Description',
'ShopOrder',
];
public function shopOrder() {
return $this->belongsTo('App\shopOrder', 'ShopOrder', 'ID');
}
}
This is the code Im executing to get the relations of 1 shoporder in the controller.
$orders = shopOrder::find('0600959e-6b92-4135-8ea8-1fa2fd92a916')->shopOrderRoutingStepPlans()->get();
In the shoporder migration I defined the primary key:
$table->string('ID')->unique();
$table->primary('ID');
In the shoporderroutingstepplans migration I defined the foreign key as followed.
$table->string('ID')->unique();
$table->primary('ID');
$table->foreign('ShopOrder')
->references('ID')
->on('shoporders');
You must switch the order of the last two parameters:
From
return $this->hasMany('App\shopOrderRoutingStepPlan', 'ShopOrder', 'ID');
To
return $this->hasMany('App\shopOrderRoutingStepPlan', 'ID', 'ShopOrder');
The parameters are
model,
name of column in the linked model,
name of column in this model.

Laravel 4: Save polymorphic relationship

I'm trying to save a polymorphic relationship in laravel and can't get it to work. I either get this error: Call to undefined method Illuminate\Database\Query\Builder::save() if I do $user->provider()->save($provider)
Or I get
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'userable_type' in 'field list' (SQL: insert into 'providers' ('user_id', 'userable_type', 'userable_id') values (16, Provider, 16))
if I switch it around and do $provider->user()->save($provider); as suggested in Call to undefined Builder::save() when saving a polymorphic relationship
From what little documentation I could find on polymorphic relationships, it seems the userable_type/id stuff goes in the parent table, and since User is my parent table, rather than Provider, the 2nd method seems to be the wrong way to do it.
At a guess I'd say the problem is with my morphTo/morphOne methods, but I've no clue how to fix them since the documentation for those methods has nothing to say about their parameters. My provider table might be set up a bit differently from what laravel expects, since it doesn't have an incremental id field as the primary key; the primary key is the foreign key and is named user_id.
This is my register code:
public function postRegister()
{
$input = Input::all();
$user = $this->user;
$validator = Validator::make($input, $user::$rules);
if($validator->passes())
{
$user->username = $input['username'];
$user->email = $input['email'];
$user->password = Hash::make($input['password']);
$user->save();
if($input['account_type'] == 0)
{
$provider = new Provider();
$provider->user_id = $user->id;
//$provider->user()->save($provider);
$user->provider()->save($provider);
}
return 'Success';
}
else
{
return Redirect::back()->withInput($input)->withErrors($validator->messages());
}
}
User model:
<?php
class User extends Validatable implements UserInterface, RemindableInterface
{
use UserTrait, RemindableTrait;
protected $table = 'users';
public function userable()
{
return $this->morphTo();
}
}
Provider Model:
<?php
class Provider extends Validatable
{
protected $table = 'providers';
protected $primaryKey = 'user_id';
public $timestamps = false;
public function user()
{
return $this->morphOne('User', 'userable');
}
}
You can call it like this:
$provider->user()->save($user);

relationship array null when eager loading in laravel

I am having issues getting the relationship array back when eager loading in laravel 4. for example:
controller:
foreach (Apps::with('extra')->get() as $app)
{
print_r($app->toArray());//returns array but my relationship array at the bottom says null
echo $app->extra; //this will show my relationship details
}
model:
class Apps extends Eloquent
{
protected $connection = 'mysql_2';
protected $table = 'apps';
public $timestamps = false;
protected $primaryKey = 'name';
public function host()
{
return $this->belongsTo('Hosts','name');
}
public function extra()
{
$this->primaryKey='app_ip';
return $this->hasone('Extra','ip');
}
//other functions below.......
}
class Extra extends Eloquent
{
protected $connection = 'mysql_3';
protected $table = 'extra';
public $timestamps = false;
protected $primaryKey = 'ip';
public function app(){
return $this->belongsTo('Apps', 'app_ip');
}
mysql:
My mysql tables were not created through laravel they were previously existent. the app_ip column in the Apps table relates to the ip column in the extra table. it is a 1 to 1 relationship and I have specified the primary key in the relationship function. I am getting relationships back so I know that it is working.
I am able to get relationship data back when I call the function directly, but it does not show the relationship data when I try and print the full array. The main goal is to be able to return both the relationship columns and the app columns in one response.
You need to do this:
$apps = Apps::all();
$apps->load('extra');
foreach ($apps as $app)
{
print_r($app->toArray()); // prints your relationship data as well
}
What you have should work and iterating through the collection or using ->load() to eager load shouldn't make a difference. Are you using the visible restriction on your models? If so you will need to include the relationships.
class Apps extends Eloquent {
protected $visible = array(
'id',
'name',
'created_at',
'extra', // Make the relationship 'visible'
);
public function extra()
{
return $this->hasMany('Extra');
}
}

Categories