How to make relationship between two models and update the database - php

It's me again but now I need some more help from you, I have some version of shopping cart and the whole idea is when I click on the product button the database to be update with the informations which user(id) has order that product(id). First I make orders table with informations(id, product_name, price), other table is users table (id, user_name) and the final table user_order table(id, user_id, order_id);
After that I make two models, one is the Orders model for the products and the second one is the User model. The relationship that I want to make is between this two models.
User model function:
public function orders(){
return $this->belongsToMany('App\Orders', 'user_order', 'user_id', 'order_id');
// return $this->belongsToMany('App\Orders');
}
Orders model function:
public function users(){
return $this->belongsToMany('App\User', 'user_order', 'order_id', 'user_id');
//return $this->belongsToMany('App\User');
}
This is the main html where I show all products with the submit button:
<div class="row">
#foreach($orders as $order)
<div class="col-sm-4 col-lg-4 col-md-4">
<div class="thumbnail">
<img src="http://placehold.it/320x150" alt="">
<div class="caption">
<h4 class="pull-right">{{ $order->cena }}</h4>
<h4>{{ $order->order_name }}
</h4>
<p>See more snippets like this online store item at <a target="_blank" href="http://www.bootsnipp.com">Bootsnipp - http://bootsnipp.com</a>.</p>
</div>
<div class="ratings">
<p class="pull-right">15 reviews</p>
<p>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
</p>
</div>
<div class="btn-group center">
Order this product!
</div>
<br>
</div>
</div>
#endforeach
Controller function:
public function makeOrder(Request $request, $id){
$user = User::where('email', $request['email'])->first();
$findorder = Orders::find($id);
//$user->orders()->detach();
$user->orders()->attach(Orders::where('id', $findorder))->first();
return redirect()->back();
}
And the route:
Route::get('/add-to-database/{id}',[
'uses' => 'AppController#makeOrder',
'as' => 'product.makeOrder'
]);
The whole idea is how to make function after submiting the button the table user_order to be updated with the id of the user, and id of the product.
Any help?

Your makeOrder() should be as:
public function makeOrder(Request $request, $id) {
$user = User::where('email', $request->get('email'))->first();
// this is to make sure that order is available in database
$order = Orders::findOrFail($id);
$user->orders()->attach($order->id);
return redirect()->back();
}

Related

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

Updating/Adding value to array in Laravel 8

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();

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()

Laravel Collection get one of values by key

I'm new to Laravel and I'm trying to get one of the values in one collection by one ID retrieved from another collection.
My function returns 2 Collections:
public function index()
{
$category = BlogCategory::all(['id', 'name']);
$post = BlogPost::orderBy('id', 'desc')->take(14)->get();
return view('blog.index', ['posts' => $post], ['categories' => $category]);
}
In a foreach loop I'm getting values from collections:
#foreach($posts as $post)
#if($loop->iteration > 2)
<div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
<a href="#">
<img src="#" alt="">
<p class="post-category">{{ $categories->get($post->category_id) }}</p>
<h5 class="post-title">{{ $post->title }}</h5>
</a>
</div>
#endif
#endforeach
I'm partially getting the result as you can see in the image below, but I want to get only the name.
Here is the code that I'm trying to figure out
{{ $categories->get($post->category_id) }}
If there is a better or correct way to do it, let me know.
Blog Posts migration:
public function up()
{
Schema::create('blog_posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->longText('content');
$table->mediumText('slug');
$table->bigInteger('author_id')->unsigned();
$table->bigInteger('category_id')->unsigned();
$table->timestamps();
$table->foreign('author_id')->references('id')->on('blog_authors');
$table->foreign('category_id')->references('id')->on('blog_categories');
});
}
You should put in place the relationships between BlogPost and BlogCategory models, seen that you already have a category_id field in BlogPost model, i.e.:
in BlogPost Model:
public function category(){
return $this->belongsTo(\App\BlogCategory::class);
}
in BlogCategory Model:
public function posts(){
return $this->hasMany(\App\BlogPost::class);
}
Next you can eager load categories with the $posts in your controller with only two queries:
public function index()
{
$posts = BlogPost::with('category')->orderBy('id', 'desc')->take(14)->get();
return view('blog.index', compact('posts'));
}
Then in your view you can access each $post->category object directly because eager loaded in the controller:
#foreach($posts as $post)
#if($loop->iteration > 2)
<div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
<a href="#">
<img src="#" alt="">
<p class="post-category">{{ $post->category->name }}</p>
<h5 class="post-title">{{ $post->title }}</h5>
</a>
</div>
#endif
#endforeach
It could be optimized, first, you need to make relation one to many from categories to posts
first: make sure that you have in posts migrations category_id column
Second: Open Category Model and write this method this will allow you to fetch posts that belong to the category
public function posts(){
return $this->hasMany(\App\Post::class);
}
Third: open shop model and write this method this will allow you to fetch category that belongs to the post
public function catgeory(){
return $this->belongsTo(\App\Category::class);
}
Finally: you will edit your view like this one
#foreach($posts as $post)
<div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
<a href="#">
<img src="#" alt="">
<p class="post-category">{{ $post->category->title }}</p>
<h5 class="post-title">{{ $post->title }}</h5>
</a>
</div>
#endforeach
and of course, you wouldn't call categories in your controller anymore
public function index()
{
$post = BlogPost::orderBy('id', 'desc')->take(14)
->with('category')->get();
return view('blog.index', ['posts' => $post]);
}
Maybe it better use a relation to drive this situation. You can load in the controller the data in this way.
In the Model Post:
function categories(){
return $this->belongsToMany('App\BlogCategory')->select(array('id', 'name');
}
Maybe is hasOne -> the relationship if you don't have a table pivot...
In the Controller:
public function index()
{
$data['posts'] = BlogPost::orderBy('id', 'desc')->take(14)->with('categories')->get();
return view('blog.index', $data);
}
In the View:
#foreach($posts as $post)
#if($loop->iteration > 2)
<div class="col-sm-6 col-md-3 d-flex justify-content-center other-post">
<a href="#">
<img src="#" alt="">
<p class="post-category">{{ $post->categories->name }}</p>
<h5 class="post-title">{{ $post->title }}</h5>
</a>
</div>
#endif
#endforeach
this line $categories->get($post->category_id) return for you an array of category, so the solution for you here is just like bellow:
{{ $categories->get($post->category_id)['name'] }}

Passing data through pivot tables?

I have three tables, the activity, the category and the activity_categories table.Each activity may belong to many categories therefore the category_id and activity_id are saved in activity_categories.
I am trying to get only one category per product, because to display use one category image per activity but on search I have to show them in all belonging categories.I have created my models as follow:
class Activity extends Model
{
protected $table = "activities";
public function category()
{
return $this->belongsToMany('App\Category','activity_categories');
}
}
//Controller
public function userActivities()
{
$user_id = Auth::user()->id;
$activities = Activity::all()->where('user_id', $user_id);
return view('user_profile.activities', compact( 'activities' ));
}
//View
#foreach($activities as $activity)
<div class="col-lg-4 col-md-4 col-xs-12" id="profile-card">
<div class="widget-head-color-box navy-bg p-lg text-center"
style="background-image: url('{{asset('/images/categories/'.$activity->category->first()->image)}}')">
<img src="/storage/profile/{{Auth::user()->image}}" class="img-small-profile" alt="profile">
<button id="heart-favorite" class="btn btn-danger btn-circle btn-outline"
type="button"><i
class="fa fa-heart"></i></button>
</div>
<div class="widget-text-box">
<h3 class="media-heading m-t-md"><b>{{$activity->title}}</b></h3>
<h5 class="media-heading m-t-md" style="text-align: justify">
{{$activity->description}}<br><br>
</h5>
</div>
</div>
#endforeach
When i use dd($activity->category->first()->image) it shows the data but when i place the same in the view id shows the error "Trying to get property of non-object"

Categories