How can I create a Many to Many relationships using the custom polymorphic table?
model_has_tags
$table->increments('id');
$table->integer('tag_id';
$table->string('model_type');
$table->integer('model_id');
tags
$table->increments('id');
$table->string('name');
user
$table->increments('id');
$table->string('full_name');
I try this but not working.
Tag Model
public function users()
{
return $this->morphedByMany(User::class, 'model');
}
User Model
public function tags()
{
return $this->morphToMany(Tag::class, 'model');
}
error :
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'stormport.models' doesn't exist (SQL: select `tags`.*, `models`.`model_id` as `pivot_model_id`, `models`.`tag_id` as `pivot_tag_id`....
How to solve this?
Found the solution:
User Model
public function tags()
{
return $this->morphToMany(Tag::class, 'model', 'model_has_tags');
}
Related
I know this question has been asked a lot but all answers didn't seem to work for me - or at least the questions I found were about the pivot table.
I have a many to many relationship (User - Appointment) which is joined by the pivot table "apointment_user", see migrations below.
Schema::create('appointment_user', function (Blueprint $table) {
$table->unsignedInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->unsignedInteger('appointment_id')->nullable();
$table->foreign('appointment_id')->references('id')->on('appointments');
$table->primary(['user_id','appointment_id']);
$table->timestamps();
});
Schema::create('appointments', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->dateTime('date');
$table->string('location');
$table->dateTime('departure');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->date('last_login')->nullable();
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
class User extends Model {
protected $with = ['appointments'];
public function appointments() : BelongsToMany {
return $this->belongsToMany(Appointment::class);
}
}
class Appointment extends Model {
public function users() : BelongsToMany {
return $this->belongsToMany(User::class);
}
}
I have a user with the ID 1 and about 10 appointments, which I do attach to the relationship in a seeder. The pivot table has 10 records, as intended (User ID is always 1).
However, if I dump my User object using dd(User::find(1)), the relationship is always an empty collection. However, a 1:n relationship (between a role works well).
Does anybody see what I'm missing? Any help is appreciated.
Many thanks and kind regards
Edit
I just tried some other kind of dumping. I've simply returned my User-Object as JSON-response and there the relationship is filled with 10 appointments... strange.
Though it seems that your table and column names are as Laravel would guess, have you tried expliciting the names?
class User extends Model {
protected $with = ['appointments'];
public function appointments() : BelongsToMany {
return $this->belongsToMany(Appointment::class, 'appointment_user', 'user_id', 'appointment_id');
}
}
class Appointment extends Model {
public function users() : BelongsToMany {
return $this->belongsToMany(User::class, 'appointment_user', 'appointment_id', 'user_id');
}
}
I am looking for a solution for storing comments in the database, but it is not difficult at all:
In one table wants to write comments from several modules on the website.
I am currently creating a table using code 'comments table':
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('module_id')->unsigned();
$table->integer('parent_id')->unsigned();
$table->text('body');
$table->timestamps();
});
}
Comments modules table:
public function up()
{
//
Schema::create('comment_module',function (Blueprint $table){
$table->increments('id');
$table->string('title',190);
$table->string('name',190)->unique();
$table->text('body');
$table->timestamps();
});
}
for now everything is okay, but i have problem with select all comments for each blog post,gallery, etc..
blog, gallery - name of modules.
code for Map.php model
public function comments(){
return $this->hasMany(Comment::class,'module_id');
}
CommentModule.php model
public function comments(){
return $this->hasMany(Comment::class,'module_id');
}
Comment.php
public function module(){
return $this->belongsTo(CommentModule::class);
}
and now how to pass a 'mmodule_id' ?
normal use with any relationships for one table will be like that:
$map->comments->body . . etc.
but for that construction don`t work, yes of course i can use raw query and use join, right ?
Is any option to use a Eloquent?
IMHO for what I understood you want to attach comments to more than one Eloquent Model. There is a clean example in the laravel docs with Polymorphic Relations
As summary you have to add two fields on the comments table: commentable_id(integer) and commentable_type (string).
After that you declare the relation on the Comment model:
public function commentable()
{
return $this->morphTo();
}
And you can use the comments() relation in each model you want to attach comments, i.e.:
class Post extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
class Map extends Model
{
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
Now you can retrieve comments as usual:
$post->comments;
To attach a new comment to a parent:
$post->comments()->create([array of comment attributes]);
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.
I have tables in my database schema as follows,
Is it pivot table?
How can I define relationship in eloquent model?
class Role extends Model {
public $timestamps = false;
public function permissions() {
return $this->hasMany('App\Models\RolePermission', 'permissions_id');
}
}
Is this correct way to define relationship? Please help me to understand.
and
class RolePermission extends Model {
public $timestamps = false;
public function role() {
return $this->belongsTo('App\Models\Role', 'roles_id');
}
}
The problem is that you need to name your table permission_role to follow the design pragma.
Role Schema
Schema::create('roles', function(Blueprint $table){
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Permission schema
Schema::create('permissions', function(Blueprint $table){
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Then you just need the permission_role table:
Permission_Role schema
Schema::create('permission_role', function(Blueprint $table){
$table->increments('id');
$table->integer('permission_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->integer('role_id')->unsigned();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
});
Then you just set up your models like this:
class Role {
public function permissions() {
return $this->hasMany(App\Permission::class);
}
}
Then of course your permission class
class Permission {
public function role() {
return $this->belongsToMany(App\Role::class);
}
}
its a many to many relationship bond together by a pivot table Permission_Role. there for each table belongsToMany not hasOne or hasMany
class Role {
public function permissions() {
return $this->belongsToMany(App\Permission::class);
}
}
class Permission {
public function role() {
return $this->belongsToMany(App\Role::class);
}
}
I seen to of got tangled in Laravel's ORM with the following:
Scenerio: All Users have a Watchlist, the Watchlist contains other Users.
I can't seem the get the relationships to work correctly as they are cyclical, so far I have the following:
class UserWatchlist extends Model
{
protected $table = 'UserWatchlist';
public function Owner() {
return $this->belongsTo('App\User');
}
public function WatchedUsers() {
return $this->hasMany('App\User');
}
}
Schema::create('UserWatchlist', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('Users')->onDelete('cascade');
$table->integer('watched_id')->unsigned();
$table->foreign('watched_id')->references('id')->on('Users')->onDelete('cascade');
$table->timestamps();
});
class User extends Model
{
public function Watchlist() {
return $this->hasOne('App\UserWatchlist');
}
public function WatchedBy() {
return $this->belongsToMany('App\UserWatchlist');
}
}
It is not pulling through the correct in formation i'm expecting. Am I missing something fundamental?
Since UserWatchlist is a pivot table, i suppose you are facing a many to many relationship with both the elements of the relation being the same model (User)
If that is the case, you should not build a model for the pivot table UserWatchlist but all you have to do is to set the relation between the users through the pivot table:
class User extends Model
{
//get all the Users this user is watching
public function Watchlist()
{
return $this->belongsToMany('User', 'UserWatchlist', 'user_id', 'watched_id' );
}
//get all the Users this user is watched by
public function WatchedBy()
{
return $this->belongsToMany('User', 'UserWatchlist', 'watched_id', 'user_id' );
}
}
Check here for more info on many-to-many relationship