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 :)
Related
There is a model ObjectType and a model GuestOptions
I want to create a pivot table, I do this
public function up()
{
Schema::create('object_type_options', function (Blueprint $table) {
$table->unsignedBigInteger('object_type_id');
$table->unsignedBigInteger('guest_option_id');
$table->foreign('object_type_id')->references('id')->on('object_types')->onDelete('cascade');
$table->foreign('guest_option_id')->references('id')->on('guest_options')->onDelete('cascade');
$table->primary(['object_type_id','guest_option_id']);
});
}
In the model I define the relation ObjectType , but there is no result
public function options()
{
return $this->belongsToMany(GuestOptions::class,'object_type_options');
}
What am I doing wrong?
Can give two basic and quick solutions.
public function options()
{
return $this->belongsToMany(GuestOptions::class,'object_type_options','object_type_id','guest_option_id');
}
you can also use the relation more clearly like below. but need to change some attributes in the database.
public function options()
{
return $this->belongsToMany(GuestOptions::class);
}
And Table need to change
public function up()
{
//table name changed
Schema::create('guest_options_object_type', function (Blueprint $table) {
$table->unsignedBigInteger('object_type_id');//actual table name
$table->unsignedBigInteger('guest_options_id'); //actual table name
$table->foreign('object_type_id')->references('id')->on('object_types')->onDelete('cascade');
$table->foreign('guest_options_id')->references('id')->on('guest_options')->onDelete('cascade');
$table->primary(['object_type_id','guest_option_id']);
});
}
Let's say, I have an Event model, which has more participants of various models (Player, Coach, Admin) through polymorphic relation and a pivot table (EventParticipant), which also contains a boolean column participate. I want to get participants through $event->participants which retrieves a collection of players, coaches, and admins through a polymorphic relation.
I have something similar created with standard non-polymorphic relation in trainings, like this:
class Training extends Model
{
/**
* Training has more players.
*/
public function players() {
return $this->belongsToMany('App\Player', 'training_player')
->using('App\TrainingPlayer')
->withPivot('participate');
}
}
class TrainingPlayer extends Pivot
{
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'participate' => 'boolean'
];
}
How could this be modified in the case of events, where participants() can be either Player, Coach, or Admin model? (Maybe something with MorphPivot class but I can't imagine how.)
(Instead of player_id (in TrainingPlayer class) which refers to id of the Player model, there are two columns role and rollable_id (in EventParticipant class) which refers to id of the Player, Coach, or Admin model, respectively)
class Event extends Model
{
/**
* Event has more participants (players, coaches, or admins).
*/
public function participants() {
//
}
}
class EventParticipant extends MorphPivot
{
//
}
Any help would be appreciate. :) Thx
I have been looking for something similar and came up with a solution. As per Jonas comment, you can't have different Models in 1 related set but you can have 1 for each model using 1 pivot table.
You can now query this with \App\Team::find(1)->with(['managers', 'users'])->get();
Schema::create('associations', function (Blueprint $table) {
$table->id();
$table->string('association_type');
$table->integer('association_id');
$table->integer('team_id');
$table->integer('meta')->nullable();
$table->timestamps();
});
Schema::create('managers', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
Schema::create('teams', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
class Manager extends Model
{
public function teams()
{
return $this->belongsToMany('\App\Team', 'associations')->using('App\Association');
}
}
class Team extends Model
{
public function managers()
{
return $this->morphedByMany('App\Manager', 'association')->using('App\Association');
}
public function users()
{
return $this->morphedByMany('App\User', 'association')->using('App\Association');
}
}
class User extends Authenticatable
{
public function teams()
{
return $this->belongsToMany('\App\Team', 'associations')->using('App\Association');
}
}
// App/Association
use Illuminate\Database\Eloquent\Relations\MorphPivot;
class Association extends MorphPivot
{
protected $table = 'associations'; // not sure if this is needed
}
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.
I have 2 tables clients and maintenance_packages and I'm trying to list all clients and their maintenance package but keep getting the following error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'maintenance_packages.client_id' in 'where clause' (SQL: select * from `maintenance_packages` where `maintenance_packages`.`client_id` = 2 and `maintenance_packages`.`client_id` is not null limit 1)
I'm guessing it the way I've set up the relationships? Below is my DB Migrations, Models & Controller.
Clients DB
public function up()
{
Schema::create('clients', function(Blueprint $table) {
$table->increments('id');
$table->string('name', 55);
$table->string('email', 100);
$table->integer('maintenance_id')->unsigned();
});
}
Maintenance DB
public function up()
{
Schema::create('maintenance_packages', function(Blueprint $table) {
$table->increments('id');
$table->string('name', 55);
$table->integer('hours');
$table->decimal('price');
});
}
Client Model
namespace App;
use App\MaintenancePackage;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
protected $table = 'clients';
public $timestamps = false;
public function maintenance()
{
return $this->hasOne(MaintenancePackage::class);
}
}
Maintenance Model
namespace App;
use App\Client;
use Illuminate\Database\Eloquent\Model;
class MaintenancePackage extends Model
{
protected $table = 'maintenance_packages';
public $timestamps = false;
public function client()
{
return $this->belongsTo(Client::class);
}
}
Controller
public function index()
{
$clients = Client::with('maintenance')->get();
return view('clients.index', compact('clients', 'maintenance'));
}
Any help would be great.
In your Client Model replace
public function maintenance()
{
return $this->hasOne(MaintenancePackage::class);
}
with
public function maintenance()
{
return $this->BelongsTo(MaintenancePackage::class, 'maintenance_id');
}
Now In your Maintenance Model replace
public function client()
{
return $this->belongsTo(Client::class);
}
with
public function client()
{
return $this->hasOne(Client::class, 'maintenance_id');
}
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');
}