How to make relationship without using modelname_id in laravel? - laravel

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');

Related

Do i need a One-to-Many polymorphic relationship?

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.

How to solved in Laravel relations null value

Im tru to use to last version of laravel and i have small problem with Laravel relationship One to Many
Im try to connect products with categories
This is my code of Product model
public function categories()
{
return $this->belongsTo('App\Category');
}
this is my code of Category model
public function products()
{
return $this->hasMany('App\Product');
}
This is my code in controller
$products = Product::with('categories')->get();
dd($products);
this is my code from migration files
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('category_id');
$table->string('name')->unique();
$table->string('slug')->unique();
$table->string('keywords')->nullable();
$table->string('price');
$table->text('description')->nullable();
$table->text('image')->nullable();
$table->timestamps();
$table->foreign('category_id')->references('id')->on('categories');
});
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->string('keywords')->nullable();
$table->timestamps();
});[![enter image description here][1]][1]
If someone know how to solved this problem I'll be very grateful
Firstly relation comes with eager loading.
Please update your codes according to single usage
In Product Model
public function category()
{
return $this->belongsTo('App\Category');
}
In Controller
$products = Product::with('category')->get();
dd($products[0]->category);
You are telling relationships name is categories, so laravel belongsTo will look categories_id instead category_id.
You can rename your relationships name as category() or
give your relationships foreign key to laravel like this;
return $this->belongsTo('App\Category', 'category_id', 'id');

Call to a member function post() on null on many to many relationship

I have created two table to store post information:
Posts table where I store overall information except categories.
Migration file of each table looks like this:
posts
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->string('slug');
$table->longText('excerpt');
$table->longText('description');
$table->tinyInteger('feature')->default(1);
$table->enum('status',['publish','draft']);
$table->string('image');
$table->timestamps();
});
post_categories
Schema::create('post_categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('category_id')->nullable();
$table->unsignedBigInteger('post_id')->nullable();
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('post_id')->references('id')->on('posts');
$table->timestamps();
});
Now, I have following function in PostCategory model:
public function post(){
return $this->belongsToMany(Post::class);
}
Now, when I try to fetch data using following:
\App\Models\PostCategory::find(5)->post()->orderBy('created_at')->get();
I get call to member function post() on null
What should I do to get post with the category 5?
You misunderstood some concepts.
Here your relationship is between post and categories.
In post Model
public function categories(){
return $this->belongsToMany(Category::class,'post_categories','post_id','category_id');
}
In the Category model
public function posts(){
return $this->belongsToMany(Post::class,'post_categories','category_id','post_id');
}
Now, You're free to access posts from category and categories from post.
$post = Post::with('categories')->where('id',5)->first();
By this, you'll get a post with its categories.
$category= Category::with('posts')->where('id',5)->first();
By this, you'll get category with its posts.
Check more detail how many to many work
Edit:-
If by using post you want to make a condition in the categories then.
$post = Post::with('categories')->whereHas('categories', function($q){
$q->where('id',5);
})->get();

Fetching Relationship Model Data

I have the Below Table Structure
Users table
id- integer
name-string
Casefiles table
id- integer
user_id- foreign_key
name-string
Followups table
id- integer
date- date
casefile_id-foreign_key
I'm using the below Relationship between this models
User.php
public function casefiles()
{
if ($this->hasRole(['sales_executive'])) {
return Casefile::where('user_id', $this->id);
}
}
Casefile.php
public function user()
{
return $this->belongsTo('App\User');
}
public function followups()
{
return $this->hasMany('App\FollowUp');
}
Followup.php
public function casefile()
{
return $this->belongsTo('App\Casefile');
}
I want to fetch Users followups directly. How can i achive this ?
you need to use hasManyThrough() in your User.php you can add this,
public function followUps()
{
return $this->hasManyThrough('App\FollowUp','App\Casefile');
}
then you can normally call the followups using User::with('followUps')->find(1)->followUps
I have noticed that you are checking role in your relationship $this->hasRole(['sales_executive'] this may occur error as you are not if the statement is false. I think you take another approached and handle that as well. for more information on hasManyThrough prefer this link
This should be the case for a HasManyThrough Relationship.
In your case it should be
// Followups migration
Schema::create('followups', function (Blueprint $table) {
$table->bigIncrements('id');
$table->date('date');
$table->unsignedBigInteger('casefile_id')->nullable();
$table->timestamps();
$table->foreign('casefile_id')
->references('id')
->on('casefiles');
});
// Casefile migration
Schema::create('casefiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->unsignedBigInteger('user_id')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users');
});
// User.php
public function followups() {
return $this->hasManyThrough(FollowUp::class, Casefile::class);
}
// YourController.php
$user = User::all()->first();
dd($user->followups);

Laravel 5.4 belongsToMany relationship returns empty

In Laravel 5.4 I'am trying to set up a Many To Many Relation. but the belongsToMany returns empty! Here's my migrations and models.
botusers Table:
public function up()
{
Schema::create('botusers', function (Blueprint $table) {
$table->increments('id');
$table->integer('t_id');
$table->string('first_name');
$table->string('last_name');
$table->string('username');
$table->string('mobile');
$table->timestamps();
});
}
candidates Table:
public function up()
{
Schema::create('candidates', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('token');
$table->string('degree');
$table->integer('age');
$table->text('desc');
$table->string('photo_url');
$table->string('cv_url');
$table->timestamps();
});
}
Third table, botuser_candidate Table:
public function up()
{
Schema::create('botuser_candidate', function (Blueprint $table) {
$table->integer('botuser_id');
$table->integer('candidate_id');
});
}
and the votes() method in Botuser Model:
public function votes()
{
return $this->belongsToMany(Candidate::class)->get();
}
When I fire the votes() method returns an empty array. and I also tested bellow method too,
public function votes()
{
return $this->belongsToMany(Candidate::class,'botuser_candidate','botuser_id','candidate_id')->get();
}
What I missed here? What should I do?
Edit:
I also added the foreign keys to the relation but the result is still same!
I would suggest you remove the get() method on the belongsToMany
Then query the database with
$c=new App\Candidate;
$c->with('votes')->get()
if you still want to use $c->votes() then you would have to do some changes to your functions. Lets use scope to achieve it.
public function candidates()
{
return $this->belongsToMany(Candidate::class,'botuser_candidate','botuser_id','candidate_id');
}
public function scopeVotes($query)
{
return $query->with("candidates")->get();
}
Then now we can call $v->votes() and it should return all your record.
Calling get() directly on belongsToMany method will return empty array.

Resources