I have two models called DataKelurahan and RegistrasiPasien and have a one-to-many relationship, but I can't access the relationship.
I have made a form for adding patient and save it to the registrasi_pasiens table and it works well. but when I try to display the relation data, it doesn't work properly.
In the registrasi_pasiens table, I have 1 record with kelurahan_id = 3. Then, I try to access it via php artisan tinker with these command:
$kelurahan = App\Domain\DataKelurahan\Models\DataKelurahan::find(3) works fine and data is exist.
$pasien = App\Domain\RegistrasiPasien\Models\RegistrasiPasien::find(2007000001) works fine and the data is exist with kelurahan_id = 3
$kelurahan->pasiens the result is null. Shouldn't it show the pasien data that has kelurahan_id = 3?
$kelurahan->pasiens->nama and the result is like this PHP Notice: Trying to get property 'nama' of non-object in D:/PROFESSIONAL/PROJECT/WEB DEVSeval()'d code on line 1 => null
I don't have any idea what's wrong with my codes. Much appreciate for your help guys.
Below are the models that I have made:
DataKelurahan.php
<?php
namespace App\Domain\DataKelurahan\Models;
use Illuminate\Database\Eloquent\Model;
use App\Domain\RegistrasiPasien\Models\RegistrasiPasien;
class DataKelurahan extends Model
{
protected $fillable = ['nama_kelurahan', 'nama_kecamatan','nama_kota'];
public function pasiens(){
return $this->hasMany('RegistrasiPasien');
}
}
RegistrasiPasien.php
<?php
namespace App\Domain\RegistrasiPasien\Models;
use Illuminate\Database\Eloquent\Model;
use App\Domain\DataKelurahan\Models\DataKelurahan;
class RegistrasiPasien extends Model
{
protected $fillable = [
'nama',
'alamat',
'telepon',
'rt',
'rw',
'tgl_lahir',
'jenis_kelamin'
];
public function kelurahan(){
return $this->belongsTo('DataKelurahan');
}
}
And below are my database tables:
data_kelurahans
Schema::create('data_kelurahans', function (Blueprint $table) {
$table->increments('id');
$table->string('nama_kelurahan');
$table->string('nama_kecamatan');
$table->string('nama_kota');
$table->timestamps();
});
registrasi_pasiens
Schema::create('registrasi_pasiens', function (Blueprint $table) {
$table->increments('id');
$table->integer('kelurahan_id')->unsigned();
$table->string('nama');
$table->string('alamat');
$table->char('telepon', 15);
$table->integer('rt');
$table->integer('rw');
$table->date('tgl_lahir');
$table->string('jenis_kelamin');
$table->timestamps();
});
Schema::table('registrasi_pasiens', function (Blueprint $table){
$table->foreign('kelurahan_id')->references('id')->on('data_kelurahans')->onDelete('cascade');
});
From Docs:
Eloquent will automatically determine the proper foreign key column on
the model. By convention, Eloquent will take the "snake case"
name of the owning model and suffix it with _id.
So, Eloquent probably got your foreign key name wrong so you must override the foreign key by passing additional arguments to the hasMany/belongsTo method:
public function pasiens(){
return $this->hasMany('RegistrasiPasien','kelurahan_id');
}
public function kelurahan(){
return $this->belongsTo('DataKelurahan','kelurahan_id');
}
Related
There are two Models User and Submission and a User can have any number of submissions in which he is referenced as Author. I have set up the relationship according to the documentation and
the result of hasMany() is working fine. Only the belongsTo() method does not return the expected objects.
Here is the migration of my models:
Schema::create('users', function (Blueprint $table) {
$table->id();
});
Schema::create('submissions', function (Blueprint $table) {
$table->id();
$table->foreignId( 'author' );
$table->foreign( 'author' )->references('id')->on('users');
});
And these are the relationships within my models:
class User extends Authenticatable {
public function submissions() {
return $this->hasMany( 'App\Submission', 'author' );
}
}
class Submission extends Model {
public function author() {
return $this->belongsTo( 'App\User', 'author' );
}
}
Now, in my controller I want to execute this code:
$author = Submission::find(1)->author;
dd($author);
But, instead of the user object, the stored integer value of the author ID is printed. The relationship does not seem to be resolved via the author() method.
On the other hand, when I fetch a user and their submissions, everything works as expected, i.e. the submissions are printed as objects:
$u = User::find(1)->submissions;
dd($u);
But the relation from Submission to User does get resolved properly, when I do not define a custom foreign key with belongsTo and rename the colum to author_id.
The configuration that works is this one:
//migration for Submissions table
Schema::create('submissions', function (Blueprint $table) {
$table->id();
$table->foreignId( 'author_id' );
$table->foreign( 'author_id' )->references('id')->on('users');
});
//within Submission model
public function author() {
return $this->belongsTo( 'App\User' );
}
I have the feeling that I'm missing something. Is there any additional link I have to make? I browsed through the documentation and the web for solutions, but to no success. If there is no other solution, I'll follow with renaming the column. But I'd rather understand the cause of my problem and work with my original design.
you should not name relation functions and fields using the same string.
When you have a column author and a public function author() laravel goes for column content first.
Add '_id' to the column, so you do not need to define referenced field in $this->belongsTo( 'App\User', 'author' );.
I have the beginnings of a Laravel application with only two models: User and Project.
There is a many-to-many relationship between Users and Projects, A single User can be working on many Projects, and a single Project can be worked on by many Users.
The problem I'm experiencing has manifested itself in two ways:
After migrating and seeding my DB with basic data, I manually create a row in the project_user pivot table, linking references to the first entries of the users and projects tables: INSERT INTO project_user (user_id, project_id) VALUES (1, 1). I then boot up Tinker in order to test the relationship. Accessing all Projects through the User model works as expected: User::find(1)->projects (returns a valid collection of Project models), however, the inverse relationship: Project::find(1)->users returns an empty collection, when it should be returning the User model referenced in the pivot table.
And, when using a Seeder file to seed the project_user table like so:
public function run()
{
$project = Project::first();
$admin = User::first();
if (isset($project) && isset($admin)) {
echo "Project: $project\n";
echo "User: $admin\n";
// FIXME: Why isn't this working?
$project->users()->attach($admin);
// The inverse below also fails for the same reason
// $admin->projects()->attach($project);
}
}
Which causes the seed file to fail with the error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'project_id' cannot be null (SQL: insert intoproject_user(created_at,project_id,updated_at,user_id) values (2020-02-02 17:01:04, ?, 2020-02-02 17:01:04, 1))
I've scoured my code, as well as the internet looking for a solution, to no avail. The problem must either be some very tiny mistake in my code, improper use of some function, or invalid order of operations. It's clear to me that there must be a problem with the association on the Project side, but I've literally compared Users and Projects side-by-side at every step and I can't figure out what's wrong. I'll paste the relevant code sections below, and if there's any additional information or code I can provide, I'm more than happy to do so. Thanks in advance for your help!
Here are the model definitions:
class User extends Authenticatable
{
public $type;
// Here is the relationship to the Projects this User is working on
public function projects()
{
// SELECT * FROM project_user WHERE user_id = $user->id
return $this->belongsToMany(Project::class)->withTimestamps();
}
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
class Project extends Model
{
public $id;
public $name;
public $deleted_at;
// Here is the relationship to the Users working on this Project
public function users()
{
// SELECT * FROM project_user WHERE project_id = $project->id
return $this->belongsToMany(User::class)
->withTimestamps();
}
protected $fillable = [
'name',
];
protected $casts = [
'deleted_at' => 'datetime',
];
}
The users and projects table migrations:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->enum('type', ['admin', 'client', 'editor'])->default('client');
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->unique();
$table->integer('memberCount')->default(0)->nullable(false);
$table->timestamp('deleted_at')->nullable();
$table->timestamps();
});
}
And here is the pivot table project_user migration that sets the references:
public function up()
{
Schema::create('project_user', function(Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('project_id');
$table->timestamps();
$table->unique(['user_id', 'project_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
});
}
Try removing public $id; from your Project model (and the other redundant properties). With Eloquent, you don't need to declare the model properties that exist as columns in the backing table of the model. I believe what's happening is the $id property on your Project model is being called, which is null, because it is overriding the magic getter that Eloquent will provide for this column out of the box.
If you're declaring the properties on your model so your IDE picks them up, consider using the barryvdh/laravel-ide-helper package instead.
Okay I want to have custom field that does not exist as a column in my db table.
I followed, last part :
http://laravel.com/docs/4.2/eloquent#accessors-and-mutators
My model code:
class Car extends Eloquent{
protected $fillable = array('driverID', 'fuelRemaining');
protected $appends = array('is_driver');
public function user(){
return $this->belongsTo('user');
}
public function getIsDriverAttribute(){
return ($this->attributes['driverID'] == Auth::user()->id);
}
}
Car table:
Schema::create('cars', function(Blueprint $table)
{
$table->increments('id');
$table->integer('driverID');
$table->integer('fuelRemaining');
$table->mediumtext('desc');
$table->timestamps();
});
As you can see i want an extra field which is "is_driver" to be returned, but when I run this, this field is used to determine whether current signed in user is the driver himself by comparing the IDs.
it will output this error:
Undefined index: driverID
Not sure what am I doing wrong here, please advice.
Ah I have found why. This is a reference for future readers
In my controller I only get these two
$car = Car::where('fuelRemaining', 0)->get(array('id', 'desc'));
When i added authorID to the get array
$car = Car::where('fuelRemaining', 0)->get(array('id', 'desc', 'authorID'));
I am able to get the authorID attribute in my custom accessor mentioned in the question.
I have a customers migration table
Schema::create('customers', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('address');
$table->string('phone');
$table->string('email');
});
and a tripsheet migration table which goes like this
Schema::create('tripsheets', function(Blueprint $table) {
$table->increments('id');
$table->integer('tripsheet_num');
$table->integer('customer_id');
$table->string('date');
$table->string('customer_name');
$table->string('customer_address');
$table->string('customer_phone');
$table->string('rep_address');
$table->string('rep_phone');
});
I have also created a customer eloquent,
class Customer extends Eloquent {
public $timestamps = true;
public $table = 'customers';
protected $fillable = ['name', 'address', 'phone', 'email'];
public function tripsheets(){
return $this->belongsTo('Tripsheet', 'name', 'address', 'phone');
}
}
and a tripsheet model,
class Tripsheet extends Eloquent {
public $timestamps = true;
public $table = 'tripsheets';
protected $fillable = [];
public function customer(){
return $this->hasMany('Customer', 'name', 'address', 'phone');
}
}
and my routes.php goes like this,
Route::get('/', function()
{
return View::make('hello');
});
Route::controller('/customers', 'CustomerController');
Route::controller('/tripsheets', 'TripsheetController');
I would like to link the customer_name, customer_address, customer_phone from the tripsheet table to the name, address, phone of the customer table. I also want to know how to route them and fetch them as a json data to be used by angular JS to display the result.
now should i create a third table to link these two? Or should i call it with Customer::with('tripsheets')->all();in the routes/controller?
I also want to know how to route them and fetch them as a json data to be used by angular JS to display the result.?
I overlooked your code and after user315.. answer I see the problem. The belongsTo and hasMany has wrong arguments.
You need to change your code to the following to make it work:
class Customer extends Eloquent {
public function tripsheets(){
return $this->belongsTo('Tripsheet', 'tripsheet_num');
}
}
class Tripsheet extends Eloquent {
public function customer(){
return $this->hasMany('Customer', 'tripsheet_num');
}
}
The problem is that you have the field tripsheet_num in the table tripsheets. Laravel tries to find a field called tripsheet_id inside the tripsheets table when you use the belongsTo(Tripsheet) on Customer. In your case this key field is named different and is not found, and so the relation is not set.
Same goes for hasMany() only then it looks in the other table for the key field.
See the relation documentation for more info: One-to-one relation & hasMany
You only need the first argument in your belongsTo and hasMany method. The others are likely the reason why it's not working. They are meant for telling Eloquent what the foreign key is, and if you are specifying the foreign key as name, then it's obviously not going to work right.
Since you have proper naming conventions, Eloquent can accurately guess what they should be and you shouldn't need them.
I have following table
Schema::create('jokes_categories', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('is_active');
$table->timestamps();
});
Schema::create('jokes', function(Blueprint $table) {
$table->increments('id');
$table->string('content', 200)->unique();;
$table->enum('is_active', array('Y', 'N'));
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('jokes_categories');
$table->timestamps();
});
In the jokes table category_id is a foreign key and it has a one-to-many relationship with jokes_categories
In the model I have the following:
class Joke extends \Eloquent {
public static $rules = array();
// Don't forget to fill this array
protected $fillable = array();
public function JokesCategory(){
return $this->belongsTo('JokesCategory');
}
}
In the controller I have the following:
$jokes = Joke::all();
But it does not pull through joke_categories.name (I was under the impression that the model definition will directly help to pull related models)
What could be the solution?
Your query is just on the Joke table.
You could eagerload the categories ie.
$jokes = Joke::with('JokesCategory')->get();
See docs: http://laravel.com/docs/eloquent#eager-loading
The convention is actually camel case instead of pascal case, otherwise Laravel doesn't seem to automatically load the relationships. I made the same mistake and couldn't figure out why my relationships where not loading automatically.
public function jokesCategory()