Updating/Adding value to array in Laravel 8 - php

I am new developer, and I seem to be stuck on handling arrays in laravel. I am using Laravel 8, and I cant seem to solve this situation.
I am building an internal recruitment site, where once a manager posts a job, employees will be able to apply to those specific jobs. I have defined the table in the database to have the "applicants" as an array consisting of the user_id's. However, I seem to not be able to add more than one array to it.
Below is my Recruitment Model
class Recruitment extends Model
{
use HasFactory;
protected $fillable = [
'title',
'salary',
'term_start',
'term_end',
'deadline',
'details',
'status',
'applicants',
];
public function user(){
return $this->belongsTo("\App\Models\User");
}
protected $casts = [
'applicants' => 'array'
];
}
Next is my migration (I am using text format, because the DB on the server is older and does not support json)
public function up()
{
Schema::create('recruitments', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->decimal('salary', 10, 2);
$table->date('term_start');
$table->date('term_end');
$table->date('deadline');
$table->longText('details');
$table->string('status');
$table->text('applicants')->nullable();
$table->timestamps();
});
}
Here is my blade
<div class="container">
<div class="row">
<div class="card col-sm-12 py-3">
<div class="card-header border d-flex justify-content-between align-items-center">
<h3 class="w-75">{{ $job->title }}</h3>
<div class="w-25">
<p class="my-0 my-0">Created at: <span class="text-info">{{ $job->created_at }}</span></p>
<p class="my-0 my-0">Last updated at: <span class="text-primary">{{ $job->updated_at }}</span></p>
</div>
</div>
<div class="card-body">
// display job details here
<form action="{{ route('add-applicant', ['id' => $job->id ]) }}" method="POST" class="col-sm-12 d-flex justify-content-center align-items-center">
#csrf
<input type="text" name="user_id" id="user_id" value="{{ Auth::user()->id }}" hidden>
<button type="submit" class="btn btn-success w-25">Apply</button>
</form>
</div>
</div>
</div>
</div>
and lastly my controller
public function addApplicant($id, Request $reqst){
$job = Recruitment::find($id);
$user[] = $reqst->user_id;
$job->applicants = $user;
$job->save();
return redirect()->back();
}
While this controller will be able to save an array, it unfortunately overwrites the already existing one (let's say a second user applied). When I try to use an array_push, it does nothing, and I still end up with just one value in the array.
Sorry this was a bit of a read, but I appreciate any help I cen get with this. Thanks

Try in
public function addApplicant($id, Request $reqst){
$job = Recruitment::find($id);
$job->applicants = $reqst->user_id;
$job->save();
return redirect()->back();
}
and in Recruitment model should have
public function user()
{
return $this->belongsTo(User::class, 'applicants');
}
and migration file
$table->integer('applicants')->nullable();

Related

Delete and Update Method of CRUD is not passing all the parameters

I've implemented a modal type Update and Delete functions in my website but it always return Too few arguments to function App\Http\Controllers\AdminController::destroy(), 1 passed in D:\SUDRTest\vendor\laravel\framework\src\Illuminate\Routing\Controller.php on line 54 and exactly 2 expected
it is also the same for the Update function as well
Here is my route for the CRUD
Route::resource('papers', AdminController::class)->only(['edit', 'update', 'destroy']);
Here is the View
<li class="pdfpaperInfo">
<div class="colpdf col-1" data-label="Title:">{{ $paper->PaperTitle }}</div>
<div class="colpdf" data-label="Paper Type:">{{ $paper->PaperType }}</div>
<div class="colpdf" data-label="College:">{{ $paper->College }}</div>
<div class="colpdf" data-label="Author(s):">{{ $paper->Authors }}</div>
<div class="colpdf" data-label="Date Published:">{{ $paper->DatePublished }}</div>
<div class="pdfbtnCont">
<button class="pdfBtn redBtn" onclick="location.href='{{route('MyProfile')}}'">Back</button>
<button class="pdfBtn redBtn" id="modalOneBtn" onclick="location.href='{{route('papers.edit', $paper->PaperID)}}'">Update</button>
<button class="pdfBtn redBtn" id="modalTwoBtn">Delete</button>
</div>
</li>
<div id="modalOne" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="m1Close close">×</span>
<div class="modalinfoCont">
<h2>Update Paper</h2>
#include('admin.updatepaper')
</div>
</div>
</div>
<div id="modalTwo" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="m2Close close">×</span>
<div class="modalTwoCont modalinfoCont">
<h2>Delete Paper</h2>
<br>
Are you sure you want to delete this paper?
<br>
<br>
<div class="modalbtnCont">
<form method="POST" action="{{route('papers.destroy', $paper->PaperID) }}">
#csrf
#method('DELETE')
<button class="redBtn" type="submit">Yes</button>
</form>
<button class="redBtn" type="submit">No</button>
</div>
</div>
</div>
</div>
</div>
and the controller
public function destroy(Papers $paper, $PaperID)
{
$paper=Papers::find($PaperID);
$paper->delete();
return redirect()->back();
}
public function edit(Papers $paper, $PaperID)
{
$paper=Papers::find($PaperID);
return view('admin.updatepaper',compact('paper'));
}
public function update(Request $request,Papers $paper, $PaperID )
{
$request->validate([
'PaperTitle' => 'required',
'PaperType' => 'required',
'file' => [
'required',
File::types('pdf')
->max(12 * 1024),
],
]);
$paper=new Papers();
$file=$request->file;
$filename=time().'.'.$file->getClientOriginalExtension();
$request->file->move('assets', $filename);
$paper->file=$filename;
$paper->DatePublished=$request->DatePublished;
$paper->PaperTitle=$request->PaperTitle;
$paper->PaperType=$request->PaperType;
$paper->Authors=$request->Authors;
$paper->update();
return redirect()->back();
}
I've tried not to do it in modal form and still it kept on displaying the same error and I don't know what is the missing parameter since it doesn't tell me
You need to take another look at route-model binding.
Laravel will by default do the Papers::find($paperID) and pass the Papers model as the Papers $papers argument to your methods.
So the destroy method should be:
public function destroy(Papers $paper)
{
$paper->delete();
return redirect()->back();
}
Of course you can disable route-model binding and do your own thing but it doesn't seem necessary here.
Its not clear what you intend to do in the update method. If you want to create a new paper on update and keep the old one then change $paper->update() to $paper->save() and you should be good. But if you want to do an actual update you should do something like this:
update(Papers $paper, Request $request) {
// validate
$paper->DatePublished=$request->DatePublished;
// update other fields
$paper->save();
return redirect()->back();
}

Can't delete selected item, only delete last item added in laravel

I want to delete data based on company_id and year from my database.
sample data content
my route in web.php
Route::post('delete_master_cuti/{company_id}/{year}', [CompanyMasterCutiController::class, 'delete_master_cuti'])->name('delete_master_cuti');
my model in App\Models, I've added the company_id and year to be for the primary key
class CompanyMasterCuti extends Model
{
use HasFactory;
protected $table = 'company_master_cuti';
protected $fillable = [
'company_id', 'year', 'cuti', 'created', 'created_by', 'modified', 'modified_by',
];
protected $guarded = [];
protected $keyType = 'string';
public $timestamps = false;
protected $primaryKey = ['company_id', 'year'];
public $incrementing = false;
public function company() {
return $this->belongsTo('App\Models\Company', 'company_id', 'id');
}
}
my code in controller. when I return the results of the $master_cuti data I get the last data I entered, not the data I selected
public function delete_master_cuti(Request $request) {
$master_cuti = CompanyMasterCuti::where($request->company_id)->where($request->year);
$master_cuti->delete();
toast('Successfull', 'success');
return redirect()->route('master-cuti.index');
}
in index.blade.php I have defined the data to be deleted based on the selected company_id and year
<a href="javascript:void(0)" onclick="$('#company_id','#year').val($(this).data(['company_id','year'])); $('#deleteModalBu').modal('show');">
<i class="badge-circle badge-circle-light-secondary bx bxs-trash font-medium-1 text-danger my-1"></i>
</a>
form delete modal
<form id="form-edit" action="{{ route('delete_master_cuti', [$m_cuti->company_id, $m_cuti->year] ) }}" method="POST">
#csrf
<div class="modal-body">
<input type="hidden" id="company_id" name="company_id">
<input type="hidden" id="year" name="year">
<div class="row no-gutters">
<div class="col-md-6">
<button type="button" class="btn btn-light-secondary" data-dismiss="modal"
style="width: 100%;">
<i class="bx bx-x d-block d-sm-none"></i>
<span class="d-none d-sm-block">CANCEL</span>
</button>
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-danger ml-1" style="width: 100%">
<i class="bx bx-check d-block d-sm-none"></i>
<span class="d-none d-sm-block">DELETE</span>
</button>
</div>
</div>
</div>
</form>
I want to delete data based on the company_id and year I chose, but why is the deleted data the last time I entered? how to solve my problem? anyone, help me.
Have you check the response from "public function delete_master_cuti(Request $request)" by return $request->all(), whether company_id & year in method?
you must specify the column name (company_id and year) in the query. for example :
public function delete_master_cuti(Request $request) {
$request->validate([
'company_id' => 'required',
'year' => 'required'
]);
$master_cuti = CompanyMasterCuti::where('company_id',$request->company_id)->where('year', $request->year);
$master_cuti->delete();
toast('Successfull', 'success');
return redirect()->route('master-cuti.index');
}
and add softDelete in your model and add deleted_at column in your database table
use Illuminate\Database\Eloquent\SoftDeletes;
class CompanyMasterCuti extends Model
{
use HasFactory, SoftDelte;
...
}
and you can add the code in your blade file for show validation error
#if(count($errors) > 0)
<div>
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
#endif

Livewire multi select form data

I'm using laravel 8 and needs to get data selected from a form selected data and insert only Clinic_id and Service_id on my ServClinic table
here is my models
needs to save data from a many to many relationship and get data further
my Clinic Model
<?php
class Clinic extends Model
{
use HasFactory;
protected $table = "clinics";
public function services(){
return $this->belongsToMany(ServiceData::class,'serv_clinics');
}
}
and
My serviceData Model
<?php
class ServiceData extends Model
{
use HasFactory;
protected $tabel = "service_data";
public function clinic(){
return $this->belongsToMany(Clinic::class,'serv_clinics');
}
}
and
ServeClinic Model
<?php
class ServClinic extends Model
{
use HasFactory;
protected $tabel ="serv_clinics";
}
and view is
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-4 pb-2 mb-3 border-bottom">
<h1 class="h2">اضافة خدمة بالعيادة</h1>
</div>
#if(Session::has('message'))
<div class="alert alert-success" role="alert">{{Session::get('message')}}</div>
#endif
<form class="form-horizontal" wire:submit.prevent="storeServices">
<div class="form-group">
<label class="col-md-4 control-label">اختار العيادة</label><br/>
<div class="col-md-4" wire:ignore>
<select class="sel_categories form-control" name="clinics[]">
#foreach($clinics as $clinic)
<option value="{{$clinic->id}}">{{$clinic->name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">اختارالخدمات</label><br/>
<div class="col-md-4" wire:ignore>
<select class="form-control" name="services[]" multiple="multiple">
#foreach($services as $service)
<option value="{{$service->id}}">{{$service->name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label"></label>
<div class="col-md-4">
<button type="submit" class="btn btn-primary">حفظ</button>
</div>
</div>
</form>
</main>
needs to get clinic_id and serve_id and save it in ServClinic table
my migration file is
public function up()
{
Schema::create('serv_clinics', function (Blueprint $table) {
$table->id();
$table->bigInteger('clinic_id')->unsigned();
$table->bigInteger('serve_id')->unsigned();
$table->timestamps();
$table->foreign('clinic_id')->references('id')->on('clinics')->onDelete('cascade');
$table->foreign('serve_id')->references('id')->on('service_data')->onDelete('cascade');
});
}
If you are in selec2 multiples element, I think you first must get this data and get the collection of clinic models to be attached to services
public $clinics = []; // or whatever is the property for clinics ids array
public $services = []; // property of serviceData ids array
public function storeServices()
{
$clinicCollection = Clinic::whereIn('id',$clinics)->get();
foreach($clinicCollection as $clinic) {
$clinic->attach($services);
}
}
if you follow the Laravel docs about the many-many intermediate table (https://laravel.com/docs/8.x/eloquent-relationships#many-to-many) you will see don't need the ServClinics model. Only create the migration for clinic_service_data intermediate table.
Of course, this is the simplest way for my point. Now, if you go on with your solution, then you can do it like:
public function storeServices()
{
$clinicCollection = Clinic::whereIn('id',$clinics)->get();
$servDataCollection = Servicedata::whereIn('id',$services)->get();
foreach($clinicCollection as $clinic) {
foreach($servDataCollection as $servData) {
ServClinic::create([
'clinic_id' => $clinic->id,
'serve_id' => $servData->id
]);
}
}
}
And of course, instead foreach statements you can filter the collections

How to show summary data in Laravel Blade inside of ForEach Loop?

I am trying to display a ForEach loop on my view that shows each code type. That part works. I am having trouble figuring out how to display a count of how many pieces of code (stored in another table) exist for each code type. I don't understand how to use the id of the code_type to query the code_type_selected table and to return that count.
In my CodeType model
protected $fillable = [
'name',
'color',
'icon'
];
public function codeTypesSelected() {
return $this->hasMany(CodeTypesSelected::class, 'code_type_id', 'id');
}
In my CodeTypeSelected model
protected $fillable = [
'code_type_id',
'code_id',
];
public function codeTypes() {
return $this->belongsTo(CodeType::class, 'id', 'code_type_id');
}
In my controller
public function index(Request $request)
{
$codeTypes = CodeType::latest()->get();
$codeTypesSelected = CodeTypesSelected::latest()->get()->groupBy('code_type_id');
//dd($codeTypesSelected);
return view('code_layout.index', compact('codeTypes', 'codeTypesSelected'));
}
And in my view
<!-- /. ROW -->
<div class="row">
#foreach($codeTypes as $codeTypeItem)
<div class="col-md-3 col-sm-12 col-xs-12">
<div class="panel panel-primary text-center no-boder bg-color-{{ $codeTypeItem->color }}">
<div class="panel-left pull-left {{ $codeTypeItem->color }}">
<i class="fa fa-{{ $codeTypeItem->icon }} fa-5x"></i>
</div>
<div class="panel-right">
<h3>
{{ count($codeTypesSelected) }}
</h3>
<strong> {{ $codeTypeItem->name }} </strong>
</div>
</div>
</div>
#endforeach
</div>
<!-- /. ROW -->
Have you tried this
CodeType::latest()->withCount('codeTypesSelected')->get()

Receiving Argument #2 should be an array in laravel

I banged my head against the walls for 2 days now and I can't seem to shake this error.
I am receiving this error:
ErrorException (E_WARNING)
array_map(): Argument #2 should be an array
What I am trying to do: Each user can have a list of urls in the database. The same url can be in two or more user account, so it is a many to many relationship.
My UrlsController looks like this:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Urls;
use Illuminate\Http\Request;
use Auth;
class UrlsController extends Controller
{
public function __construct() {
$this->middleware('auth');
}
public function index(User $user)
{
return view('editurl', compact('user'));
}
public function store(User $user) {
$user_id = Auth::user()->id;
$data = request()->validate([
'user_id' => $user_id,
'url' => 'required',
]);
auth()->user()->userurls()->create([
'user_id' => $data['user_id'],
'url' => $data['url'],
]);
return redirect("/url/" . auth()->user()->id);
}
}
My Urls model looks like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Urls extends Model
{
//protected $quarded = [];
protected $fillable = ['user_id','url'];
protected $table = 'userUrls';
public function user()
{
return $this->belongsToMany(User::class);
}
}
My blade file looks like this:
#extends('layouts.pagprincipala')
#section('content')
<section id="home" class="home pt-5 pb-5">
<div class="container mb-5">
<div class="row">
<div class="col-md-8">
<h1 class="h4">Adaugare url-uri</h1>
<hr class="bg-dark w-25 ml-0">
<p>
<form action="/url/{{$user->id}}" enctype="multipart/form-data" method="post">
#csrf
<div class="row">
<div class="col-8 offset-2">
<div class="form-group row">
<label for="url" class="col-md-12 col-form-label">Adaugare URL (doar emag si pcgarage)</label>
<input id="url"
type="text"
class="form-control{{$errors->has('url') ? 'is-invalid' : ''}}"
name="url"
autocomplete="url" autofocus>
#if($errors->has('url'))
<span class="invalid-feedback" role="alert">
<strong class="text-danger">Campul url este obligatoriu.</strong>
</span>
#endif
</div>
<div class="row pt-4">
<button class="btn btn-primary">Adaugare URL</button>
</div>
</div>
</div>
</form>
</p>
</div>
</div>
</div>
</section>
#endsection
Also, my routes look like this:
Route::get('/url/{user}', 'UrlsController#index')->name('editurl');
Route::post('/url/{user}', 'UrlsController#store')->name('updateurl');
Can you give me a suggestion on how to move forward from this ?!
The problem is in your validator:
$data = request()->validate([
'user_id' => $user_id,
'url' => 'required',
]);
You try to validate the user_id with a rule that is the user id. What you probably want to achieve is 'user_id' => 'integer', or you can drop this rule all together as you know who the user is because of Auth()->user(). This should do:
$data = request()->validate([
'url' => 'required|url', //checks if it is an URL
]);
What we don't know is how your User model is constructed. With a many to many you need a pivot table urls_users or user_urls_users with url_id and user_id which means you don't need a user_id in the userUrls table, just id and url. But that's another issue. If you want to make sure any user has any url only once, you can use the ->sync() methode.

Categories