Can someone help me?
I have an error Attempt to read property "id" on null Laravel 8 while trying to show my table
Migration Tables
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('username', 20)->unique();
$table->string('password', 20);
$table->enum('level',['admin', 'manager', 'pegawai']);
$table->timestamps();
});
Schema::create('employees', function (Blueprint $table) {
$table->id();
$table->foreignId('id_user')
->constrained('users')
->onUpdate('cascade')
->onDelete('cascade');
$table->string('nama_pgw', 50);
$table->string('alamat');
$table->string('no_telp', 13);
$table->string('email', 30)->unique;
$table->timestamps();
});
Employee Model
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Employee extends Model
{
use HasFactory;
protected $table = 'employees';
protected $fillable = ['nama_pgw', 'username', 'alamat', 'no_telp', 'email'];
public function user(){
return $this->hasOne(User::class);
}
}
User Model
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasFactory;
protected $table = 'users';
protected $fillable = ['username', 'password', 'level'];
public function employee(){
return $this->belongsTo(Employee::class, 'id_user', 'id');
}
}
User Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
$users = User::get();
return view('user/index', compact('users'));
}
}
Employee Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Employee;
use App\Models\User;
class PegawaiController extends Controller
{
public function index()
{
$pegawai = Employee::get();
return view('pegawai/index', compact('pegawai'));
}
}
This is my view
<select name="id_user" id="username" class="uk-select">
<option>- pilih username -</option>
#foreach ($pegawai as $emp)
option value="{{$emp->users->id}}">{{$emp->users->nama_pgw}}</option>
#endforeach
</select>
Is it any problem on foreign key? I keep checking on typos possibility but everything seems right.
thank you!
Your relation in the employee Model is "user" while you are referring to it in blade view as "users".
Also, to run your code you can update your view:
<select name="id_user" id="username" class="uk-select">
<option>- pilih username -</option>
#foreach ($pegawai as $emp)
<option value="{{$emp->user->id}}">{{$emp->user->nama_pgw}}</option>
#endforeach
</select>
Edited:
I will also suggest optimizing your query by using eager loading. In your current code, it will execute n+1 queries where 1 query to retrieve employees and N queries to retrieve user for each employee
Update it with below code:
class PegawaiController extends Controller
{
public function index()
{
$pegawai = Employee::with(['user'])->get();
return view('pegawai/index', compact('pegawai'));
}
}
Related
I have models:
Page:
id
slug
Image
id
file
Video
id
file
I need the Page model to have a relation with several Image and Video models through one relationship, like
foreach($page->attachments as $attachment)
{
// $attachment can be Image or Video
}
And inserts like
$attachments = [$image, $video];
$page->attachments()->saveMany($attachments);
I tried to make a morph relationship, but nothing comes of it, please help.
Create an Attachment Model and attachments Table with the following columns/properties:
id
file
page_id
type (video/image)
then you could add hasmany relationship to your page model
public function attachments()
{
return $this->hasMany(Attachment::class);
}
Then you can fetch the attachment like you tried
In order to achieve this you have to make table for relations. This table should be defined like this:
page_image_video
id
page_id
image_id
video_id
And fields page_id, image_id and video_id should be a foreign keys. This is a table where you will save you attachments for your page. After that, you can define method attachments() in you Page Model with hasMany().
Create Migration :
Page Table :
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string("slug");
$table->timestamps();
});
Image Table :
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string("file");
$table->timestamps();
});
Videos Table :
Schema::create('video', function (Blueprint $table) {
$table->increments('id');
$table->string("file");
$table->timestamps();
});
Pageables Table :
Schema::create('pageables', function (Blueprint $table) {
$table->integer("pages_id");
$table->integer("pageable_id");
$table->string("pageable_type");
});
Create Model :
Now, we will create Pages, Images and Video model. we will also use morphToMany() and morphedByMany() for relationship of both model.
Video Model :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
use HasFactory;
protected $table='video';
protected $primaryKey='id';
protected $guarded = [];
public function pages()
{
return $this->morphToMany(Pages::class, 'pageable');
}
}
Images Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Images extends Model
{
use HasFactory;
protected $table='image';
protected $primaryKey='id';
protected $guarded = [];
public $timestamps = false;
public function pages()
{
return $this->morphToMany(Pages::class, 'pageable');
}
}
Pages Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
class Pages extends Model
{
use HasFactory;
protected $table='page';
protected $primaryKey='id';
protected $guarded = [];
public $timestamps = false;
public function posts()
{
return $this->morphedByMany(Images::class, 'pageable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany(Video::class, 'pageable');
}
}
Retrieve Records :
$pages = Pages::find(1);
foreach ($pages->posts as $post) {
var_dump($post);
}
foreach ($pages->videos as $video) {
print_r('<br>');
//var_dump($video);
}
Create Records :
$page = Pages::find(1);
$img = new Images();
$img->file = "test insert";
$page->posts()->save($img);
All done.
Im working on my Laravel project, and have a problem with many-to-many relationship : cannot use "sync" function to store the data in Intermediary Table.
Im following the tutorial in this series : Part 37 - Adding Tag UI/UX
Problem seems to be with this code line : $post->tags()->sync($request->tags, false);
It throws back the error :
BadMethodCallException Call to undefined method App\Post::tags()
I have tried to use attach function instead of sync, does not work.
I dont know which part of code could lead to this issue.
Pls tell me if u guys notice anythings. Tysm !
Post.php (Model)
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = "posts";
public function category(){
return $this->belongsTo('App\Category');
}
public function user(){
return $this->belongsTo('App\User');
}
public function tag(){
return $this->belongsToMany('App\Tag', 'post_tag');
}
}
Tag.php (Model)
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
protected $table = "tags";
public function post(){
return $this->belongsToMany('App\Post', 'post_tag');
}
}
create_post_tag_table.php (migrations - Intermediary Table)
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostTagTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('post_tag', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('post_id')->unsigned()->nullable();
$table->foreign('post_id')->references('id')->on('posts');
$table->bigInteger('tag_id')->unsigned()->nullable();
$table->foreign('tag_id')->references('id')->on('tags');
});
}
}
posts.create.blade.php (views - select multiple tags)
<select class="form-control select2-multi" name="tags[]" multiple="multiple" style="width:100%;">
#foreach($tags as $tag)
<option value='{{ $tag->id }}'>{{ $tag->name }}</option>
#endforeach
</select>
PostsController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Post;
use App\Tag;
use App\User;
class PostsController extends Controller
{
public function create()
{
$tags = Tag::all();
return view('posts.create')->with('tags', $tags);
}
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'category_id' => 'required',
]);
$post = new Post;
$post->title = $request->input('title');
$post->description = $request->input('description');
$post->content = $request->input('content');
$post->category_id = $request->input('category_id');
$post->user_id = auth()->user()->id;
$post->status = $request->input('status');
$post->save();
$post->tags()->sync($request->tags, false);
return redirect('/posts')->with('success', 'Post created.');
}
}
You have defined the relationship as tag in your Post model but you are calling tags. You should change it to tags since it is a belongsToMany relationship.
public function tags()
{
return $this->belongsToMany('App\Tag', 'post_tag');
}
I'm using Laravel and I'm trying to create a related record from an array using the method HasOne::create. It inserts the related record, but does not add a new id to main model's foreign field. What am I doing wrong?
Thx
$contact = new Contact();
$contact->company = $data['company'] ?? '';
$contact->comment = $data['comment'] ?? '';
$contact->save();
$contact->address()->create($data['address']);
...
var_dump($contact->address_id); exit();
The relations work fine, all fields specified. By ->get() methods they're returning correct models
var_dump result - null
Also, the $data['address'] contains valid data, specified as fillable at Address model and address_id is fillable for Contact model
UPD:
Contact class:
public function address()
{
return $this->hasOne(Address::class, 'id', 'address_id');
}
Address class:
public function contact()
{
return $this->belongsTo(Contact::class, 'id', 'address_id');
}
$data['address'] contains an array with ['raw' => 'someaddress'], raw field is in $fillable
There's a nice guide on Eloquent Relationships here.
Based on that I just tested the code below and it works fine (using Laravel 5.8)
Migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Cars extends Migration
{
public function up()
{
Schema::create('owners', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('cars', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
$table->integer('owner_id')->unsigned()->index()->nullable();
$table->foreign('owner_id')->references('id')->on('owners');
});
}
public function down()
{
Schema::drop('cars');
Schema::drop('owners');
}
}
Models
//App/Owner.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Owner extends Model
{
protected $fillable = ['name'];
public function car()
{
return $this->hasOne(Car::class);
}
}
//App/Car.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Car extends Model
{
protected $fillable = ['name'];
public function owner()
{
return $this->belongsTo(Owner::class);
}
}
Test
<?php
namespace Tests\Feature;
use App\Owner;
use Tests\TestCase;
class TestCars extends TestCase
{
/**
* A basic feature test example.
*
* #return void
*/
public function testExample()
{
$owner = new Owner(['name' => 'Jack']);
$owner->save();
$owner->car()->create(['name' => 'Nice Car']);
}
}
SQL
select * from cars;
------------
# id, name, created_at, updated_at, owner_id
'1', 'Nice Car', '2019-06-21 13:08:58', '2019-06-21 13:08:58', '1'
select * from owners
-------------
# id, name, created_at, updated_at
'1', 'Jack', '2019-06-21 13:08:58', '2019-06-21 13:08:58'
just started with Laravel. I have attached my user and profile models along with the profile controller. My goal is to assign the foreign key uID in the profile table automatically. Any help will be appreciated.
user model file
namespace App;
use Illuminate\Database\Eloquent\Model;
class user extends Model
{
// specify which attributes can be filled out during registration
public $timestamps = false;
protected $fillable=['firstname','lastname','email','password',];
public function profile(){
return $this->hasOne(profile::class,'pID','uID');
}
}
profile model file
namespace App;
use Illuminate\Database\Eloquent\Model;
class profile extends Model
{
//
public $timestamps = false;
protected $fillable = ['summary','uID'];
public function user(){
return $this->belongsTo(user::class,'uID','pID');
}
}
profile migration file
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProfilesTable extends Migration
{
public function up()
{
// create profile table
Schema::create('profiles', function (Blueprint $table) {
$table->increments('pID');
$table->timestamp('created_at')->useCurrent();
$table->string('summary')->default('');
$table->integer('uID')->unsigned();
$table->foreign('uID')->references('uID')->on('users')->onDelete('cascade');
});
}
}
profile controller file
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\profile;
class ProfileController extends Controller
{
public function store(Request $request)
{
// used to store user profile after validation
$this->validate($request,[
'summary' => 'required'
]);
$profile = new profile([
'summary' => $request->get('summary'),
]);
$profile->save();
return redirect()->route('profile.create')->with('success','Profile created');
}
}
Change your migration file,
As you wanted to define your relationship later, So your foreign id field should be nullable.
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProfilesTable extends Migration
{
public function up()
{
// create profile table
Schema::create('profiles', function (Blueprint $table) {
$table->increments('pID');
$table->timestamp('created_at')->useCurrent();
$table->string('summary')->default('');
$table->integer('uID')->nullable()->unsigned();
$table->foreign('uID')
->references('uID')
->on('users')
->onDelete('cascade');
});
}
}
And If you wanted to assign Logged in user after create profile,
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\profile;
class ProfileController extends Controller
{
public function store(Request $request)
{
// used to store user profile after validation
$this->validate($request,[
'summary' => 'required'
]);
$profile = new profile([
'summary' => $request->get('summary'),
'uID' => auth()->user()->id,
]);
$profile->save();
return redirect()->route('profile.create')->with('success','Profile created');
}
}
If you aren't providing value in your program, you need to provide default value on table definition level.
According to your description it seems you are missing to create a profile after creating a user record.
I am new to Laravel 5.1. I'm watching a tutorial video and in video teacher is using this code to insert data in database :
<?php
namespace App\Http\Controllers;
use App\comments;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class CommentController extends Controller
{
public function getCommentNew()
{
$data = array(
'commenter' => 'soheil' ,
'comment ' => 'Test content' ,
'email' => 'soheil#gmail.com' ,
'post_id' => 1 ,
) ;
comments::create( $data );
}
}
I am doing the steps like him but I have a problem , all fields ecept created_at and updated_at will be empty like this :
this is my comments model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class comments extends Model
{
protected $fillable = ['commenter,email,post_id,comment,approved'];
public function post(){
return $this->belongsTo('App\posts');
}
}
and this is migration :
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCommentsTable extends Migration
{
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->unsignedinteger('post_id');
$table->string('commenter') ;
$table->string('email') ;
$table->text('comment') ;
$table->boolean('approved');
$table->timestamps();
});
}
public function down()
{
Schema::drop('comments');
}
}
You haven't properly set the $fillable attribute in your Model, try with :
// in your model
protected $fillable = [
'commenter','email','post_id','comment','approved'
];
You have to define column names saperately on fillable array as shempignon described on above answer
Ex: ['column1', 'column2'...]
not in a single string. Each column name needs to be an array element
Try this and it'll be fine :) , you just forgot protected $table = 'comments';
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class comments extends Model
{
protected $table = 'comments';
protected $fillable = ['commenter','email','post_id','comment','approved'];
public function post(){
return $this->belongsTo('App\posts');
}
}