I've got a problem i can't get through, here are my models:
Cloth.php
public function selling(): BelongsTo
{
return $this->belongsTo(Selling::class);
}
Selling.php
public function clothes(): HasMany
{
return $this->hasMany(Cloth::class);
}
And now it's anything ok and pretty basic... but then came this model:
Accessory.php
public function selling(): BelongsTo
{
return $this->belongsTo(Selling::class);
}
And now it's the problem: I need (i think) a polymorphic relationship but i can't understand how to make it in this specific case.
I have 2 starting models to morph to 1 model but every example i found have 1 starting model to morph to 2 models.
Do i need a polymorphic relationship?
I can't really get out of this.
Thanks!
You are basically looking for a one to many polymorphic relationship. Here is how to do it:
Let's say your tables are structured like bellow;
Schema::create('sellings', function (Blueprint $table) {
$table->id();
$table->integer('relation_id');
$table->string('relation_type');
$table->timestamps();
});
Schema::create('accessories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('details');
$table->timestamps();
});
Schema::create('cloths', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description');
$table->timestamps();
});
Selling.php
public function relation(){
return $this->morphTo();
}
Cloth.php
public function selling(){
return $this->morphOne(Selling::class, 'relation');
}
Accessories.php
public function selling(){
return $this->morphOne(Selling::class, 'relation');
}
Then, you can query using bellow approach;
$selling = Selling::findOrFail(1)->relation;
Now when you dd($selling) you get exactly what you are looking for from a correspondent table;
Please remember that the relation_type field needs to exactly correspond the model. See bellow screenshot for example;
What happens here is when you create a polymorphic function called test the database fields need to follow with test_type corresponding to model and test_id corresponding to the id of the model/database table.
Related
I'm trying to use two different Category model to the same items table.
I'v got 3 models
SystemCategory
Schema::create('system_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
UserCategory
Schema::create('user_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->integer('user_id');
$table->timestamps();
});
Item
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->integer('categoryable_id');
$table->string('categoryable_type');
$table->timestamps();
});
Item category could be either from system_categories or user_categories table
I saw some Polymorphic relations but its about how two different models can belongs to one category, not about how model can belongs to two different category models
Thanks.
It can be done, first thing your schema looks ok but you want to set catagoryable_id to a bigInteger to match the id columns of the 2 category tables.
Then you would set your models up
class Item extends Model
{
public function categoryable()
{
return $this->morphTo();
}
}
class SystemCategory extends Model
{
public function items()
{
return $this->morphMany('App\Item', 'categoryable');
}
}
class UserCategory extends Model
{
public function items()
{
return $this->morphMany('App\Item', 'categoryable');
}
}
Obviously this is presuming your models are in the App namespace
I have a Laravel migration like this
usergroups:
Schema::create('usergroups', function (Blueprint $table) {
$table->integer('id')->primary();
$table->string('name');
$table->string('slug');
});
users:
Schema::create('users', function (Blueprint $table) {
$table->integer('nik')->primary();
$table->string('name');
$table->string('username');
$table->string('password');
$table->string('telp', 15);
$table->integer('usergroup_id');
$table->rememberToken();
$table->timestamps();
});
Schema::table('users', function ($table) {
$table->foreign('usergroup_id')->references('id')->on('usergroups')->onDelete('cascade');
});
User model
public function group()
{
return $this->belongsTo(Usergroup::class, 'id');
}
Usergroup model
public function user()
{
return $this->hasMany(User::class, 'usergroup_id');
}
I get blank data with this
$petugas = User::find(1);
return $petugas->group;
anyone help me, please...
This is not a One to One relationship i.e (user has one phone and one phone belongs to one user)
A group has many users in this case, One to Many relationship
You're migrating the users table twice, move the foreign key to the migration
Schema::create('users', function (Blueprint $table) {
$table->integer('nik')->primary();
$table->string('name');
$table->string('username');
$table->string('password');
$table->string('telp',15);
$table->integer('usergroup_id');
$table->foreign('usergroup_id')->references('id')->on('usergroups')->onDelete('cascade');
$table->rememberToken();
$table->timestamps();
});
Hope this helps
First of all, this is not a One to One relationship. This is a One to Many relationship. The relation you have build in wrong way according to migration files.
The relation code block should look like this.
public function group()
{
return $this->hasMany(Usergroup::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
Some more info:
In your scenario there might be two possible fact.
A user has many groups, but a group is belongs to only one
user.
A group has many users but a user is belongs to only one
group.
Fact 1: In this case the foreign key column should place in groups table. To follow the convention make the foreign column name user_id in groups table. And the code should look like this
public function groups()
{
return $this->belongsTo(Usergroup::class);
}
public function user()
{
return $this->hasMany(User::class);
}
Fact 2: In this case the foreign key column should place in users table. To follow the convention make the make the foreign column name group_id in users table And the relation code should look like this
public function group()
{
return $this->hasMany(Usergroup::class);
}
public function users()
{
return $this->belongsTo(User::class);
}
i got it...
this on user model
public function group()
{
return $this->belongsTo(Usergroup::class,'usergroup_id');
}
and this on usergroup model
public function user()
{
return $this->hasMany(User::class,'usergroup_id');
}
I am trying to learn Laravel-> one to one relationship.
In given code link(join) should be dependent on name(user2s table) and title(post2s table) but the link(join) is dependent on my_id(user2s table) and title(post2s table)
My full codes
Migrations:-
user2s table
Schema::create('user2s', function (Blueprint $table) {
$table->increments('my_id');
$table->string('name');
$table->string('email');
$table->string('password');
$table->string('remember_token');
$table->timestamps();
});
post2u table:
Schema::create('post2s', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->text('content');
$table->timestamps();
$table->tinyInteger('is_admin');
});
Model User2
protected $primaryKey = 'my_id';
public function postx(){
return $this->hasOne(Post2::class, 'title', 'name');
}
My Route Code
Route::get('user/{id}/post', function($id){
return User2::find($id)->postx;
});
http://localhost:8000/user/abc/post
error: Trying to get property of non-object
user2s table
post2s table
Let me explain what is your issue.
error: Trying to get property of non-object, it means it can't find the result. The result object is null, so when you looking for null->postx, it can't get them anything.
You search for User2::find($id), when you use find(), it is looking for primary key. And you User2 Model primary key is my_id, and you are looking for Post2->title. It not able to find it.
More infor about find()
https://laravel.com/docs/5.5/eloquent#retrieving-single-models
Since you are looking for the Post2 title. And you are referencing from User2. It is not correct.
What you should do is
In your route.php
Route::get('user/{title}/post', function($title){
//return Post2::all();
$post = Post2::with('userx')->where('title', $title)->first();
dump($post);
dump($post->userx)//<- you can get user info via
});
In Post2 Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post2 extends Model
{
public function userx(){
return $this->belongsTo(User2::class, 'user_id');
}
}
I am trying to use one to many relationship for post and category.And for the database columns,If i use like this
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->integer('category_id');
$table->timestamps();
});
in Post model
public function Category()
{
return $this->belongsTo('App\Category');
}
in category model
public function posts()
{
return $this->hasMany('App\Post');
}
Its working if i use above method like $table->integer('category_id').But i want to use custom name like
$table->integer('cat_id') without using category_id like
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->integer('cat_id');
$table->timestamps();
});
.I am using laravel 5.4 and please help me out. Thanks.
If you check out Laravel's site on Eloquent: Relationships under One To Many relationships, you'll see:
Like the hasOne method, you may also override the foreign and local keys by passing additional arguments to the hasMany method:
return $this->hasMany('App\Comment', 'foreign_key');
return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
This is also the case for $this->belongsTo which is just an inverse One To Many relationship. So in your case:
return $this->belongsTo('App\Category', 'cat_id');
Having some problems retrieving nested relationship data. Here are my models:
class Partner extends Model
{
public function admins()
{
return $this->hasMany(Resource::class)->where('resource_type', 'Admin');
}
}
class Resource extends Model
{
public function details() {
return $this->belongsTo(ResourceDetail::class);
}
}
class ResourceDetail extends Model
{
}
When I try $this->partner->admins[0]->details it's giving null. The sql it generated is: "select * from resource_details where resource_details.id is null". I'm not quite sure why is it null in the query. I must have done something wrong with the relations. I tried $this->partner->with('admins.details')->find($this->partner->id)->toArray();. It's getting the admins, but details is still null. I also tried hasManyThrough, like: return $this->hasManyThrough(ResourceDetail::class, Resource::class)->where('resource_type', 'Admin'); it finds "unknown column". This is my database structure:
Schema::create('partners', function (Blueprint $table) {
$table->increments('id');
});
Schema::create('resources', function (Blueprint $table) {
$table->increments('id');
$table->integer('partner_id')->nullable()->unsigned();
$table->foreign('partner_id')->references('id')->on('partners')
->onUpdate('cascade')->onDelete('set null');
$table->enum('resource_type', constants('RESOURCE_TYPES'))->nullable();
$table->integer('resource_detail_id')->unsigned();
$table->foreign('resource_detail_id')->references('id')->on('resource_details')
->onUpdate('cascade')->onDelete('cascade');
});
Schema::create('resource_details', function (Blueprint $table) {
$table->increments('id');
});
Do I need to change the structure? Or, how can I get the data from current structure? All I want is, a partner has many resources, and a resource has one details.
From that error I think you may be trying to call $this->partner->admins[0]->details from a model that doesn't have an id. What is $this in context to?