Laravel : How to Create Dropdown to Select FOREIGN KEY from Other Table? - php

i want to ask you how to select FOREIGN KEY (from "doa_id in "doas" table) when user create a new data (to the "notes table) in a form. This is my code :
NoteController.php
public function create()
{
return view('note/create');
}
public function store(Request $request)
{
$userId = Auth::user()->id;
Note::create([
'title' => $request->title,
'detail' => $request->detail,
'user_id' => $userId,
'mood_id' => $request->mood_id,
'doa_id' => $request->doa_id,
]);
return redirect('notes');
}
2021_05_28_020438_create_notes_table.php migration
class CreateNotesTable extends Migration
{
public function up()
{
Schema::create('notes', function (Blueprint $table) {
$table->id('note_id');
$table->string('title');
$table->date('created_at');
$table->date('updated_at');
$table->text('detail');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
//mood FK
$table->unsignedBigInteger('mood_id');
$table->foreign('mood_id')->references('mood_id')->on('moods');
//doa FK
$table->unsignedBigInteger('doa_id');
$table->foreign('doa_id')->references('doa_id')->on('doas');
});
}
public function down()
{
Schema::dropIfExists('notes');
}
}
and this is my dropdown html :
<div class="container">
<label class="form-label text-white" style="font-weight: bold;" for="doa">Doa terkait</label>
<select class="form-select" style="color: #41A7A5" aria-label="Default select example">
<option selected>Pilih doa</option>
</select>
</div>
In Dropdown option, I want to show "doa_name" based on it's "doa_id"
Thank you :)

You can put the logic in the NoteController and the view. For example, to get a collection of all options for the foreign key, pass the collection to the view.
public function create()
{
$doas = Doas::all();
return view('note/create', compact('doas'));
}
Then on the view, you can perform a foreach loop using the select HTML tag.
<div class="container">
<label class="form-label text-white" style="font-weight: bold;" for="doa">Doa terkait</label>
<select class="form-select" style="color: #41A7A5" aria-label="Default select example">
#foreach ($doas as $doa)
<option value="{{$doa-id>}}">{{$doa->name}}</option>
#endforeach
</select>
</div>
After this, it's just using the input in your store() method.

Related

Laravel 8 - Save multiple checkbox selections with separate field to pivot table

Background:
Laravel 8 + Bootstrap 5
I'm pulling a list of licence categories from database to the form.
In the form user is asked to tick which licence to assign to the user. (up to that point I'm OK)
Target
I'd like licence expiry date to be assigned to every category selected.
Code
blade.php
<div class="mb-1"><strong>Assign user's driving licence categories:</strong></div>
#foreach($categories as $category)
<div class="input-group mb-3">
<div class="input-group-text" style="width: 6ch !important;">{{$category->name}}</div>
<div class="input-group-text">
<input class="form-check-input" type="checkbox" name="categories[]" value="{{$category->id}}">
</div>
<div class="input-group-text">Expiry date</div>
<input class="form-control" type="date" name="expiry_date[]">
</div>
#endforeach
Form screenshot
pivot table migration
public function up()
{
Schema::create('driving_licence_category_user', function (Blueprint $table) {
$table->id();
$table->string('driving_licence_category_id');
$table->string('user_id');
$table->string('expiry_date')->nullable();
$table->timestamps();
});
}
models
User
public function drivingLicenceCategory()
{
return $this->belongsToMany('App\Models\DrivingLicenceCategory')
->withPivot('expiry_date')
->withTimestamps();
}
Licence
public function userHasDrivingLicenceCategory()
{
return $this->belongsToMany('App\Models\User');
}
UserController
public function store(Request $request)
{
$request->validate([
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required',
'roles' => 'required',
'categories' => 'required',
'expiry_date' => 'required'
]);
$user = User::create($request->except(['roles', 'categories', 'expiry_date']))
->syncRoles($request->roles)
->drivingLicenceCategory()->sync($request->only('categories'));
//missing code to store the expiry_date information
return redirect()->route('users.index')->with('success', 'User added successfully.');
}
Thank you for spending time on this post :)

Method Illuminate\Database\Eloquent\Collection::books does not exist.(laravel)

I am beginner of laravel, I want to store a book to books database, but after click button, it shows "Method Illuminate\Database\Eloquent\Collection::books does not exist." What am I missing?
here are my codes.
BookController
public function create()
{
return view('books.create');
}
public function store(Request $request)
{
$this->validate($request, [
'book' => 'required|max:255',
'category' => 'required',
'quantity' => 'required|numeric',
'price'=>'required|numeric',
'info'=>'required'
]);
//$request->user()->member()->books()->create([
$member=auth()->user()->member()->get();
$member->books()->create([
'book' => $request->book,
'category' => $request->category,
'quantity' => $request->quantity,
'price'=>$request->price,
'info'=>$request->info
]);
return redirect('shops')->with('success', 'successful');
}
books.create
<form action="{{route('books.store')}}" method="POST" role="form">
#csrf
#method('POST')
<div class="form-group">
<label for="book">name:</label>
<input id="book" name="book" class="form-control" placeholder="enter book name">
</div>
<div class="form-group">
<label for="category">category:</label>
<input id="category" name="category" class="form-control" placeholder="enter category">
</div>
<div class="form-group">
<label for="quantity">quantity:</label>
<input id="quantity" name="quantity" class="form-control" placeholder="enter quantity">
</div>
<div class="form-group">
<label for="price">price:</label>
<input id="price" name="price" class="form-control" placeholder="enter price">
</div>
<div class="form-group">
<label for="info">info:</label>
<textarea id="info" name="info" class="form-control" rows="10" placeholder="enter info"></textarea>
</div>
<button type="submit" class="btn-sm btn-primary">create</button>
</form>
User and Member is one to one relation, and Book belongs to one Member
Book Model
public function member()
{
return $this->belongsTo(Member::class);
}
protected $fillable = ['book','category','quantity','price','info'];
Member Model
public function books()
{
return $this->hasMany(Book::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
User Model
public function member()
{
return $this->hasOne(Member::class);
}
books,user and member migration
books migration
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('member_id');
$table->foreign('member_id')->references('id')->on('members')->onDelete('cascade');
$table->string('name');
$table->integer('quantity');
$table->integer('price');
$table->string('path');
$table->string('info');
$table->string('category');
$table->timestamps();
});
}
member migration
public function up()
{
Schema::create('members', function (Blueprint $table) {
$table->increments('id');
$table->unsignedbigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('sex');
$table->string('email');
$table->string('address');
$table->string('tel');
$table->timestamps();
});
}
user migration
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->text('profile_photo_path')->nullable();
$table->timestamps();
});
}
You are receiving a Collection from this chain of calls:
$member = auth()->user()->member()->get();
get is going to always return a Collection when called on a relationship method. If you want a single model you can call first instead:
$member = auth()->user()->member()->first();
Though first could return null so you may need to check that.
Another method to access the result of this relationship would be to use the dynamic property for the relationship member:
$member = auth()->user()->member;
Since that relationship is defined as a HasOne it knows to load it for a single result or null.
Assuming $member isn't null at this point you should be fine with the rest how it is.
$member=auth()->user()->member()->get(); returns a collection not an object of Member class. Use $member=auth()->user()->member()->first(); or $member=auth()->user()->member;
Try this
public function store(Request $request)
{
$this->validate($request, [
'book' => 'required|max:255',
'category' => 'required',
'quantity' => 'required|numeric',
'price'=>'required|numeric',
'info'=>'required'
]);
$member=auth()->user()->member;
if($member){
$member->books()->create([
'book' => $request->book,
'category' => $request->category,
'quantity' => $request->quantity,
'price'=>$request->price,
'info'=>$request->info
]);
return redirect('shops')->with('success', 'successful');
}
//Member is not found, return with error
return redirect()->back()->with('error', 'Member not found');
}
That error is due to the fact that this call $member=auth()->user()->member()->get();. It's supposed to return a Collection of Member.
So when you try to call books on a collection hold by the variable member It' won't succeed as Illuminate\Support\Collection Class doesn't define a method books you have to loop trought that collection by using a foreach loop or a each or map method from Collection.
$member->each(function($member){
$member->books()->create([
//
]);
});
Or has you have already define in User Model that user will always have a single Member by using hasOne method.
So you can use auth()->user()->member()->first(); which return a single instance of type Member on which you call books method but with that you have to be sure that the Authenticated use has already one member which is attached to him to avoid any error. even though that is the case you can always check if variable $member is not null with an if statement
$member = auth()->user()->member()->first();
if($member){
// here you can have access to `books`
$member->books()->create([
//...
]);
}

How to make simple dynamic drop list in Laravel?

I'm new at Laravel and not good with syntax. I have seen many tutorials and have read many answers, but still, my mind didn't get the point of how can I have a dropdown field for a foreign key.
I'm having one table "Section" and other "Class." I want to show the name of classes in section page.
Sections Migration
Schema::create('sections', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->integer('class_id')->unsigned();
$table->foreign('class_id')->references('id')->on('classses');
});
Classses Migration
Schema::create('classses', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->timestamps();
});
Honestly, I don't know if I should have changed my controller or not.
Blade/View
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" name="name" id="title">
</div>
<div class="form-group">
<label for="cid">Class</label>
???????????????
</div>
Index Function
public function index()
{ $sections = Section::all();
return view('sections.index', compact('sections'));
$classs = Classs::all()->pluck(['id', 'title']);
return view('sections.index')->with('classs', $classs); }
Error is Unreachable Statement at line $class & Expected string, got array at ([id,'title])
In your controller, you have a function to return the view.
Change it to include ->with(), so you can access the classes in the view:
// if the controller is not for the classes, add this up top:
use App\Classs; // include model name
$classs = Classs:all();
return view('yourView')->with('classe', $classs);
Then, in your view, you can just do this:
<div class="form-group">
<label for="cid">Class</label>
<select class="" name="cid">
<option value="null">Class</option>
#foreach($classs as $class)
<option value="{{$class->id}}">{{$class->title}}</option>
#endforeach
</select>
</div>
It loops over all the classes in your database and creates a <option> element for them. Looking at your first migration, you're using the id in the other table, so you need to set that as the value.
Change your index function to this:
public function index()
{
$sections = Section::all();
$classs = Class::all();
return view('sections.index')->with('sections', $sections)->with('classs', $classs);
}
Can you tell me where can I write conditions such as select * from class where role_id=2 etc.
Basically, in an MVC framework, you do all your queries in your controller and pass the data to the view, in which you display the data.
Laravel has a DB class which you can use for basic queries:
select * from class where role_id = 2
Would become this in Laravel, using the DB class.
DB::table('class')->where('role_id', 2)->get();
// or if it's a model:
Model::where('role_id', 2)->get();
I have now used this code in blade page
#php
use Illuminate\Support\Facades\DB;
$cid=DB::table('classses')->get();
$uid=DB::table('users')->where('role_id','3')->get();
$counter=0;
#endphp
<select class="" name="class_id">
<option value="null">Class</option>
#foreach($cid as $class)
#if($counter==0)
<option selected="selected" value="{{$class->id}}">{{$class->title}}</option>
{{$counter++}}
#else
<option value="{{$class->id}}">{{$class->title}}</option>
#endif
#endforeach
</select>

How to store and update multiple data in Laravel

I have two tables in my database: role's table and role membership's table
role's table
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('RoleName');
$table->boolean('IsAllCategory')->nullable()->default(0);
$table->boolean('IsUserCanLogin')->nullable()->default(1);
$table->timestamps();
});
role membership's table
Schema::create('role_memberships', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id');
$table->string('MembershipName');
$table->text('MembershipValue');
$table->timestamps();
});
I have a row data in my role's table with RoleName = 'Admin', then I set the membership.. everytime I store role membership data into database, it will store as two rows with same role_id..
This is my controller of Role membership
public function show($id)
{
$role = Role::findOrFail($id);
$postAdMaxImage = DB::table('role_memberships')->where('role_id', $role->id)->where('MembershipName' , 'PostAdMaxImage')->first();
$postAdExpiredDay = DB::table('role_memberships')->where('role_id', $id)->where('MembershipName' , 'PostAdExpiredDay')->first();
return view('pages/back-end/forms/role/membership')->with('role', $role)
->with('postAdMaxImage', $postAdMaxImage)
->with('postAdExpiredDay', $postAdExpiredDay);
}
public function update(Request $request, $id)
{
$role = Role::findOrFail($id);
$membership = [
['role_id' => $id, 'MembershipName' => 'PostAdMaxImage', 'MembershipValue' => $request->PostAdMaxImage ? $request->PostAdMaxImage : ''],
['role_id' => $id, 'MembershipName' => 'PostAdExpiredDay', 'MembershipValue' => $request->PostAdExpiredDay ? $request->PostAdExpiredDay : '']
];
DB::table('role_memberships')->insert($membership);
return response()->json(array($role, $membership));
}
The first problem is in show function.. I can not use first().. I want to get the data to show it into my view
<div class="form-group">
<div class="col-md-6">
<label>Membership</label><br>
<label>Maximum Gambar untuk Iklan</label>
<div class="row">
<div class="col-md-10">
<input type="text" name="PostAdMaxImage" class="form-control" value="{{$postAdMaxImage->MembershipValue}}">
</div>
<div class="col-md-2" style="padding: 0 !important">
<h5>Gambar</h5>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-6">
<label>Masa Berlaku Iklan</label>
<div class="row">
<div class="col-md-10">
<input type="text" name="PostAdExpiredDay" class="form-control" value="{{$postAdExpiredDay->MembershipValue}}>
</div>
<div class="col-md-2" style="padding: 0 !important">
<h5>Hari</h5>
</div>
</div>
</div>
</div>
The second problem is, when I want to edit the membership.. It will store as new two rows, not update the last two rows
To get the values use the value function
$postAdMaxImage = DB::table('role_memberships')->wh‌​ere('role_id', $role->id)->where('MembershipName' , 'PostAdMaxImage')->value('MembershipValue');
$postAdExpiredDay = DB::table('role_memberships')->where('role_id', $id)->where('MembershipName' , 'PostAdExpiredDay')->value('MembershipValue');
change your view to:
value="{{$postAdMaxImage}}"
value="{{$postAdExpiredDay}}"
In the second question you need to alter your update function to update the fields not create new ones
public function update(Request $request, $id)
{
$PostAdMaxImage= $request['PostAdMaxImage'];
$PostAdExpiredDay = $request['PostAdExpiredDay'];
DB::table('role_memberships')->where('role_id',$id)->where('MembershipName','PostAdMaxImage')->update(['MembershipValue'=>$PostAdMaxImage]);
DB::table('role_memberships')->where('role_id',$id)->where('MembershipName','PostAdExpiredDay')->update(['MembershipValue'=>$PostAdExpiredDay]);
return response()->json(array($role, $membership));
}

Many to Many relation in Laravel5.4

I Want to Create multi category for posts in database but I Just create one category with this code:
post.php
public function Category()
{
return $this->belongsTo('App\Category');
}
Category.php
public function posts()
{
return $this->belongsToMany('App\Post');
}
posts_table:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('category_id');
$table->string('title');
$table->integer('price');
$table->string('description');
$table->timestamps();
});
}
and view for create category is here:
<form method="post" action="/storePost">
{{csrf_field()}}
<input type="hidden" id="user_id" name="user_id" value="
{{Auth::user()->id}}">
<lable>title</lable>
<input type="text" id="title" name="title">
<label>description</label>
<input type="text" id="description" name="description">
<label>price</label>
<input type="text" name="price" id="price">
<label>Category</label>
<select name="category_id">
#foreach($categories as $category)
<option value={{$category->id}}>{{$category->name}}</option>
#endforeach
</select>
<button type="submit" id="AddProduct">add</button>
</form>
And my postcontroller to create category is:
public function store()
{
Post::create([
'user_id'=>request('user_id'),
'title' => request('title'),
'category_id'=>request('category_id'),
'description'=>request('description'),
'price'=>request('price'),
]);
return redirect('/show');
}
How I Can create multi category for one posts in table?
You are going to need to design your database somewhat differently. You need a proper join table between the two tables. Your database should look something like this:
posts
id
//other
categories
id
//other
post_categories
post_id
category_id
Once you have the database setup with a proper join. You have to define the relations a little bit differently:
// App\Models\Post
public function categories() {
return $this->belongsToMany('App\Category', 'post_categories', 'category_id', 'post_id');
}
// App\Models\Category
public function posts() {
return $this->belongsToMany('App\Post', 'post_categories', 'post_id', 'category_id');
}
You can then use attach and detach to add and remove relations:
$post = Post::find(1);
$post->categories()->attach($categoryId);
You can read more about many-to-many relationships in the Laravel Documentation.

Categories