laravel 8 update child table data from parent table - laravel

I'm working on a Laravel 8 project.
I have a payments table, it's the migration:
Schema::create('payments', function (Blueprint $table) {
$table->id();
$table->enum('gateway',['idpay','zarinpal']);
$table->unsignedInteger('res_id')->nullable();
$table->char('ref_code',128)->nullable();
$table->enum('status',['paid','unpaid']);
$table->unsignedBigInteger('order_id');
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
$table->timestamps();
});
as you can see this table has a foreign key that references on orders table, and it is orders migration:
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('amount');
$table->char('ref_code',128)->nullable();
$table->enum('status',['unpaid','paid',]);
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
I created a one to one relationship in Order model:
class Order extends Model
{
use HasFactory;
protected $guarded = [];
public function payment()
{
return $this->hasOne(Payment::class);
}
}
The problem is that when I want to use order() method on Payment class it does not work.
for example:
Payment::find(10)->order()->update(['status' =>'paid']);
I get this error:
BadMethodCallException Call to undefined method
App\Models\Payment::order()
UPDATE:
Here is Payment model:
class Payment extends Model
{
use HasFactory;
protected $guarded = [];
}
Thank you for helping me.

You should use like this a method in the payment model.
public function order()
{
return $this->belongsTo(Order::class);
}
Because you still don't have any relationship in the payment model to order.
You can check here for detailed information.
https://laravel.com/docs/8.x/eloquent-relationships#one-to-one-defining-the-inverse-of-the-relationship

You have to describe the order relation ship in the Payment model
class Payment extends Model
{
use HasFactory;
protected $guarded = [];
public function order()
{
return $this->belongsTo(Order::class);
}
}
and after that you can access the payment's order like this:
Payment::find(10)->order->update(['status' =>'paid']);

Related

Laravel Models and displaying them on view together

For a school assignment we have two tables and models players and countries
I know its either my models or my controller (I've had this problem before but in another assignment their was only one country so i just looped through a country variable and used arrays instead but this wont work for multiple countries)
When I try to display in the view i get "Trying to get property of non-object 'name' on the {{$player->country->name}} and this is the way the teacher has explicitly said we are to display it.
Currently before anything else id like to display all my players and their country names
Models
class Country extends Model
{
//
protected $table = 'countries';
protected $fillable=['name','flag'];
public function player(){
return $this->hasMany(Player::class);
}
}
class Player extends Model
{
//
protected $fillable =['name','age','role','batting','bowling','image','odiRuns','countries_id'];
public function country()
{
return $this->belongsTo(Country::class);
}
}
Tables
public function up()
{
Schema::create('countries', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('flag');
$table->timestamps();
});
}
public function up()
{
Schema::create('players', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('age');
$table->string('role');
$table->string('batting');
$table->string('bowling');
$table->string('image');
$table->string('odiRuns');
$table->integer('countries_id')->unsigned();
$table->foreign('countries_id')->references('id')->on('countries');
$table->timestamps();
});
}
Controller
use App\Player;
use App\Country;
use Illuminate\Http\Request;
class PlayerController extends Controller
{
public function index()
{
//
$players=Player::all();
return view('index',compact('players'));
}
View
#extends('layout')
#section('content')
#foreach ($players as $player )
{{$player->name}}
{{$player->age}}
{{$player->role}}
{{$player->batting}}
{{$player->bowling}}
{{$player->odiRuns}}
{{$player->country->name}}
#endforeach
#endsection
Edit
players all have country id's relating to the countries table
Tables
players table
countries table
The problem is your missing foreign key in relation. When you are defining a relationship, if you explicitly don't tell which foreign key to use for the relationship, Laravel looks for a foreign key like relationname_primarykeyoftheparenttable. In your case its country_id but in your players table the column name is countries_id. So relationship is not building and you are getting error. Change the column name or tell the relationship which foreign key to use to build the relationship.
class Player extends Model
{
protected $fillable =['name','age','role','batting','bowling','image','odiRuns','countries_id'];
public function country()
{
return $this->belongsTo(Country::class,'countries_id');
}
}
Laravel Doc

Company::find(1)->departments returns null from relationship issues

I am making a few tables having one to many relationships and I also have one to one relationships but if I solve this why it is not working maybe I can solve one to one as well.
I will provide some codes for you to have a look at.
when I go to tinker and type like "Company::find(1)->deparments", it returns null. when I check the database, foreign key is correctly added.
I also set the primary key in model.
Company table
public function up()
{
Schema::create('companies', function (Blueprint $table) {
$table->bigIncrements('company_id');
$table->string('phone');
$table->string('company_name',100);
$table->timestamps();
});
}
Department Table
public function up()
{
Schema::create('departments', function (Blueprint $table) {
$table->bigIncrements('department_id');
$table->unsignedBigInteger('company_id');
$table->foreign('company_id')->references('company_id')->on('companies')->onDelete('cascade');
$table->string('department_name',100);
$table->timestamps();
});
}
Company Model
protected $primaryKey = 'company_id';
Protected $table='companies';
Protected $fillable=['phone','company_name'];
public function users()
{
return $this->hasMany(User::class,'user_id');
}
Department Model
protected $primaryKey = 'department_id';
protected $table = 'departments';
protected $fillable = ['department_name'];
public function company()
{
return $this->belongsTo(Company::class,'company_id');
}
public function users()
{
return $this->hasMany(User::class,'department_id');
}
You missed the department relationship in Company Model inorder to call this command.
public function departments()
{
return $this->hasMany(Department::class,'department_id');
}
I think it should be like this after creating relationship,
Company::with(['deparments'])->findOrFail(1);
Hope this helps :)

(Laravel) Polymorphic relation through pivot table

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
}

Laravel Relations, Models and Migrations

I have a problem with my relations in laravel:
I have two tables, Languages and Customers.The customer just can have 1 language. These are my migrations and Models:
Migrations:
Schema::create('tbl_customers', function (Blueprint $table){
$table->increments('id');
$table->string('first_name',255);
$table->string('last_name',255);
$table->date('date_of_birth');
$table->string('email',255);
$table->string('phone_number',255);
$table->string('phone_number2',255);
$table->string('password', 255);
$table->unsignedInteger('dealer_id');
$table->string('picture_profile',255);
$table->string('occupation',255);;
//Foreign key
$table->unsignedInteger('language_id');
$table->string('about_me',255);
});
Schema::create('tbl_languages', function (Blueprint $table){
$table->increments('id');
$table->string('language',255);
});
This is the foreign Key:
Schema::table('tbl_customers', function (Blueprint $table){
$table->foreign('language_id')->references('id')
->on('tbl_languages')->onDelete('cascade');
});
These are my Models.
Customer:
class Customer extends Model{
protected $table='tbl_customers';
protected $primaryKey="id";
protected $fillable=['address_id','first_name','last_name','gender_id','date_of_birth','email','phone_number','phone_number2',
'dealer_id','picture_profile','occupation','time_zone_id','language_id','about_me'];
protected $hidden=['password'];
public $timestamps = false;
public function language(){
return $this->hasMany(Language::class);
}}
Language
class Language extends Model{
protected $table='tbl_languages';
protected $primaryKey="id";
protected $fillable=['language'];
public $timestamps=false;
public function customers(){
return $this->belongsToMany(Customer::class);
}}
So, If I make a query I have the next error:
error
why? If the migrations have the standard that Laravel says
If I change the Customer model like this:
public function language(){
return $this->hasMany(Language::class,'id','language_id');
}
It works good, but Languages no.
I wish you guys can help me.
add this to your Customer model:
public function language(){
return $this->belongsTo('App\Language');
}
and this to your Language model:
public function customers(){
return $this->hasMany('App\Customer');
}

How to access the values of a foreign key of another table using laravel

I created a custom pivot model which is SectionSubject that have an id, section_id and subject_id. I want now to access the other values related to the section_id. Here is my Sectionsubject model and section_subject table:
SectionSubject.php
class SectionSubject extends Model
{
protected $table = 'section_subject';
public function students()
{
return $this->belongsToMany(Student::class, 'section_subject_student','section_subject_id'
)->withTimestamps();
}
public function assignStudents(Student $student)
{
return $this->students()->save($student);
}
}
create_section_subject.php
Schema::create('section_subject', function (Blueprint $table) {
$table->increments('id');
$table->integer('section_id')->unsigned();
$table->integer('subject_id')->unsigned();
$table->string('schedule')->unique();
$table->string('room_no');
$table->foreign('section_id')
->references('id')
->on('sections')
->onDelete('cascade');
$table->foreign('subject_id')
->references('id')
->on('subjects')
->onDelete('cascade');
});
Now I want to fetch those values and place it on my ReservationController. I tried to use one to many relationship but it seems not working.
class ReservationController extends Controller
{
public function index()
{
$sectionSubject = SectionSubject::find(1);
//code here
return view('reservation.form', compact('sectionSubject');
}
}
you can fetch relationship by doing this
$sectionSubject = SectionSubject::with('students')->find(1);
//print your variable
echo "<pre>";
print_r($sectionSubject->toArray());
echo "</pre>";
you will find the related table data

Resources