how to get data of other table in laravel 5.2 - laravel

I am new to Laravel and i am working on the project where i want to retrieve the full details of address table including city name, state name and country name.
In routes following is the code.
$addresses = App\Address::with('countries', 'states','cities')->get();
return $addresses;
when i am running the code i get an error
BadMethodCallException in Builder.php line 2161:
Call to undefined method Illuminate\Database\Query\Builder::countries()
Please help me.
cities table
Schema::create('cities', function (Blueprint $table) {
$table->increments('id');
$table->integer('state_id')->unsigned();
$table->foreign('state_id')->references('id')->on('states');
$table->string('cityName', 50);
$table->timestamps();
});
states Table
Schema::create('states', function (Blueprint $table) {
$table->increments('id');
$table->integer('country_id')->unsigned();
$table->foreign('country_id')->references('id')->on('countries');
$table->string('stateName', 50);
$table->timestamps();
});
countries Table
Schema::create('countries', function (Blueprint $table) {
$table->increments('id');
$table->string('countryName', 50);
$table->timestamps();
});
addresses Table
Schema::create('addresses', function (Blueprint $table) {
$table->increments('id');
$table->integer('country_id')->unsigned();
$table->foreign('country_id')->references('id')->on('countries');
$table->integer('state_id')->unsigned();
$table->foreign('state_id')->references('id')->on('states');
$table->integer('city_id')->unsigned();
$table->foreign('city_id')->references('id')->on('cities');
$table->string('firstLine', 50);
$table->string('secondLine', 50);
$table->string('thirdLine', 50);
$table->string('zipCode', 50);
$table->timestamps();
});
and in models
City
class City extends Model
{
// City belongs to a State
public function city(){
return $this->hasOne('App\State');
}
public function address(){
return $this->belongsTo('Address');
}
}
State
class State extends Model
{
// State has many Cities
public function cities(){
return $this->hasMany('App\City');
}
// State belongs to a Country
public function country(){
return $this->hasOne('App\Country');
}
public function address(){
return $this->belongsTo('Address');
}
}
Country
class Country extends Model
{
// Country has many States
public function states(){
return $this->hasMany('App\State');
}
public function address(){
return $this->belongsTo('Address');
}
}
Address
class Address extends Model
{
// Address has one City
public function cities(){
return $this->hasOne('App\City','city_id');
}
// Address has one State
public function states(){
return $this->hasOne('App\State','state_id');
}
// Address has one Country
public function countries(){
return $this->hasOne('App\Country','country_id');
}
}

Now that we can access all of a post's comments, let's define a
relationship to allow a comment to access its parent post. To define
the inverse of a hasMany relationship, define a relationship function
on the child model which calls the belongsTo method:
Look One To Many
You have one Country has many states and inverse relation is the state has one country.
So you should in model State change method country() like this
public function country(){
return $this->belongsTo('App\Country');
}
and use State::with('country')
P.S.
And check the other models.

Related

Can't create one to many relationship on same model

I want to create sponsors users on my website. I use the same model as relationship.
User.php (model):
public function sponsor(): HasMany
{
return $this->hasMany(self::class, 'sponsored_id', 'sponsor_id');
}
public function sponsored(): BelongsTo
{
return $this->BelongsTo(self::class, 'sponsor_id', 'sponsored_id');
}
Sponsor rows :
Schema::table('users', function (Blueprint $table) {
$table->foreignId('sponsor_id')->nullable();
$table->foreignId('sponsored_id')->nullable();
});
My UserSeeder:
$sponsor = User::factory()->create(['name' => 'sponsor']);
$sponsor->sponsor()->save(
User::factory()->make()
);
As per your comment you are trying to retrieve one record from sponser so it should be
$sponsor->sponsor()->first()

laravel eloquent relation one to one

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

How to get parent_id count?

Users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name');
$table->string('last_name');
$table->string('referral_code')->nullable();
$table->integer('parent_id')->unsigned()->nullable();
$table->string('mobile')->unique();
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Order table
public function up()
{
Schema::create('oreders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->bigInteger('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->timestamps();
});
}
I tried first and whereHas('user') replaced it
$orderCount = Order::whereHas('user')->withCount('parent_id')->get();
return $orderCount;
I get this error.
Call to undefined method App\Order::parent_id() (View: C:\xampp\htdocs\site\bazar\resources\views\Admin\master.blade.php)
You first need to define the relationship in your models App\User and App\Order
App/User.php
class User extends Model
{
public function orders()
{
return $this->hasMany(Order::class);
}
public function parent()
{
return $this->belongsTo(User::class, 'parent_id');
}
public function children()
{
return $this->hasMany(User::class, 'parent_id');
}
}
App/Order.php
class Order extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
I do believe you want to count the number of order for a user.
But first of all, we will fix some issues / I'm suspecting you have.
Table name orders is called oreders
You don't need to verify if an order has a user Order::whereHas('user') since $table->bigInteger('user_id')->unsigned(); is not nullable. It means an order cannot exists without a user.
Not an issue but a suggestion $table->bigInteger('user_id')->unsigned(); can be simplified with $table->unsignedBigInteger('user_id');
Now the interesting part
$orderCount = Order::whereHas('user')->withCount('parent_id')->get();
return $orderCount;
In my understand you're trying to get the number of orders of of a parent of the user. I will show you some use case that may help your understanding.
// Get the total number of orders
$orderCount = Order::count();
// Get the total number of orders of a user
$userOrderCount = $user->orders()->count();
// Include the number of orders in the user attributes
$user = User::withCount('orders')->find($userId); // notice 'order' is, in fact `orders()` from the App\User methods
// Include the number of orders in the parent attributes
$parent = User::withCount('orders')->find($user->parent_id);
// Number of orders of the parent
$parentOrderCount = Order::where('user_id', $user->parent_id)->count();
// Edit: As you commented, you also want to know "The marketers can see how many people bought their code"
// I'm assuming this is the number of children (I have added the relation in the model above)
$childrenCount = $user->children()->count()
Note : when you do Order::where('user_id', $user->parent_id)->count(); you don't need to verify that the user has a parent first. parent_id will return null and user_id cannot be null. So it will just return 0

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

Show second & third model level

I kow this is known subject discussed but I'm not getting the issue solved.
This is my current app model design:
Institution is the parent model of the app, which has many branches
Branch model has a polymorphic relationship with Building model (child enttity)
Classroom model belongs to Building model (1 Building, M Classroom)
I have a show.blade.php view where I list a Branch and I have 2 tabs for Buildings & Classrooms.
I can show each building for that branch but when I can' get to show all the classrooms in that branch (the relatioship is branch->building->classroom)
I have to solve this with a custom query in controller and then pass the result to the view or there is another approach?
Im trying to show classrooms from each institution ... but classrooms are related to builings.
$a=App\Institution::find(1); //OK
$a->branches; //OK
$a->buildings; //OK
$a->buildings->classrooms //Exception with message 'Property [classrooms] does not exist on this collection instance.
Regards
Institution Model
public function branches()
{
return $this->hasMany(Branch::class);
}
public function buildings()
{
return $this->morphMany('App\Building', 'buildingable');
}
Branch Model
public function institution()
{
return $this->belongsTo(Institution::class);
}
public function buildings()
{
return $this->morphMany('App\Building', 'buildingable');
}
Building Model
public function buildingable()
{
return $this->morphTo();
}
public function classrooms()
{
return $this->hasMany(Classroom::class);
}
Classroom Model
public function building()
{
return $this->belongsTo(Building::class);
}
TABLE STRUCTURES
public function up()
{
Schema::create('institutions', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('inst_name', 30);
$table->string('inst_id_type', 10);
$table->string('inst_id_number', 10);
$table->string('inst_country', 15);
$table->string('inst_type', 15);
});
public function up()
{
Schema::create('branches', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('branch_name', 30);
$table->string('branch_id_type', 10);
$table->string('branch_id_number', 10);
$table->string('branch_country', 15);
$table->string('branch_type', 15);
$table->integer('institution_id');
});
}
public function up()
{
Schema::create('buildings', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('building_name', 30);
$table->integer('buildingable_id');
$table->string('buildingable_type');
});
}
public function up()
{
Schema::create('classrooms', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('classroom_name', 20);
$table->integer('building_id');
$table->integer('employee_id');
});
}
$a->buildings->classrooms is the problem. $a->buildings is a collection, not an eloquent model. To get the classrooms of each building, you could use a foreach loop or the each() function on the connection.
foreach example:
foreach($a->buildings as $building) {
$classrooms = $building->classrooms;
// Do stuff here...
}
each() example:
$a->buildings->each(function ($building) {
$classrooms = $building->classrooms;
// Do stuff here...
}

Resources