Two models for one Controller in Laravel (methods Edit & Update) - php

Would you please let me know if this controller SerieController is correct? As I don't think so.
There are two models in fact. One Model is Serie and the other is Mark.
When, I click on the drop down list, I don't see my items...
public function edit($id)
{
$series = Serie::with('marks')->find($id);
return view('admin.series.edit', compact('series'));
}
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required',
'fk_mark' => 'required'
]);
$series = Serie::with('marks')->find($id);
$series->name = $request->get('name');
$series->fk_mark = $request->get('fk_mark');
$series->save();
return redirect()->route('series.index')
->with('success', 'updated successfully');
}
My edit.blade.php
<form class="panel-body" action="{{route('series.update',$series->id)}}" method="POST">
<input name="_method" type="hidden" value="PATCH">
#csrf
<fieldset class="form-group">
<label for="form-group-input-1">Name</label>
<input type="text" name="name" class="form-control" id="form-group-input-1" value="{{$series->name}}">
</fieldset>
<div class="form-group">
<label for="company-content">Select Mark</label>
<select name="fk_mark" id="" class="form-control">
#foreach($series->marks as $mark)
<option value="{{$mark['id']}}">{{$mark['name_mark']}}</option>
#endforeach
</select>
</div>
Concerning the model
Model Serie
class Serie extends Model
{
protected $fillable = ['name', 'fk_mark'];
public function marks(){
return $this->belongsTo('App\Mark', 'fk_mark');
}
}
Model Mark
class Mark extends Model
{
protected $fillable = ['name_mark'];
public function series(){
return $this->hasMany('App\Serie', 'fk_mark');
}
public function cars(){
return $this->hasMany('App\Car','fk_serie');
}
}
Thank you in advance.

In your edit function you have to do this:
public function edit($id)
{
$series = Serie::with('marks')->find($id);
return view('admin.series.edit', compact('series'));
}
and in your blade you will fetch the marks like this:
$series->marks->name_mark;
and it is the same method for update function to update two tables data.
I hope it would helpful.

First of all: Which version of Laravel do you use?
Check out route model binding which would compact your functions like this:
public function edit(Serie $serie)
{
$series->load('marks');
return view('admin.series.edit', compact('series'));
}
public function update(Request $request, Serie $serie)
{
$request->validate([
'name' => 'required',
'fk_mark' => 'required'
]);
$series->load('marks');
$series->name = $request->get('name');
$series->fk_mark = $request->get('fk_mark');
$series->save();
return redirect()->route('series.index')
->with('success', 'updated successfully');
}
Further tipps for debugging:
Set 'debug' => true in your app.php
Try to use dd($serie); to see what happens to your model.
Install debugbar: composer require barryvdh/laravel-debugbar --dev
Check your database tables to see if your code successfully created the data.
Write Unit/Feature Test to validate your application logic
Provide more data in your next SO question like sql schema, error messages etc
Without the sql schema and exact problem you're facing it's very hard to debug someone else code. I hope this helps nonetheless.
Edits: grammar, spelling and last sentence fixed/added

Related

Laravel 8 error 404 page not found , I wonder where did I do wrong here?

At the most basic of understanding, I've been trying to match the route and the form action. I think that I am doing it right but I wonder why does the error keeps on showing ? I may have missed something anywhere but I just really couldn't find it. Please help. In a very tight schedule, I need to complete this project by tuesday
P.S : when i submit the form it goes to this address http://127.0.0.1:8000/profile/edit/1 .
Form
<x-layout>
<x-setting heading="Edit Staff Profile">
<div class="flex flex-col">
<form method="POST" action="/profile/edit/{{$profil->id}}" enctype="multipart/form-data">
#csrf
<div class="mb-6">
<label class="block mb-2 uppercase font-bold text-sm text-gray-700" for="images">
Profile photo
</label>
<input type="file" name="images">
</div>
Route
Route::get('profile', [UserController::class, 'index'])->middleware('auth')->name('profile');
Route::get('profile/edit/{id}', [UserController::class, 'show'])->middleware('auth');
Route::post('profile/edit/{id}', [UserController::class, 'update'])->middleware('auth');
UserController
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\Profile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class UserController extends Controller
{
public function index()
{
$id = Auth::user()->id;
$info = User::where('id', $id)->first();
return view('profile', compact('info'));
}
// public function create()
// {
// return view('staffrecord.create');
// }
public function store()
{
$attributes = request()->validate([
'name' => 'required|max:255',
'username' => 'required|min:3|max:255|unique:users,username',
'email' => 'required|email|max:255|unique:users,email',
'password' => 'required|min:7|max:255',
]);
if (auth()->attempt($attributes)) {
return redirect('/')->with('success', 'Your account has been created.');
}
return redirect('/profile')->with('errors', 'Authentication failed.');
}
public function show($id)
{
$profil = User::findOrFail($id);
return view('staffrecord.edit', compact('profil'));
}
public function edit()
{
$id = Auth::user()->id;
$profil = Profile::findOrFail($id);
return view('staffrecord.edit', compact('profil'));
}
public function update(Request $request, $id)
{
$data = Profile::findOrFail($id);
$data->staff_id = $request->staff_id;
$data->name = $request->name;
$data->gender = $request->gender;
$data->address = $request->address;
$data->email = $request->email;
$data->phonenumber = $request->phonenumber;
$data->department = $request->department;
$data->save();
return redirect('/')->route('profile');
}
}
A user may has his logins but they may not have setup their profiles so when you do such request profile find will fail and return to 404 error.
Also to make a note ALWAYS use foreign keys in Profile table linking to user id it's not necessary that a user->id say 1 will have profile->id 1.
in User model add this function:
public function profile() {
return $this->hasOne('App\Models\Profile');
}
Then load user profile in update function of controller like:
public function update(Request $request, $id){
$user = User::with('profile')->findOrFail($id);
if (is_null($user->profile){ echo 'user don't has profile'; }
//Update profile from within
$user->profile()->updateOrCreate([$request->all()]);
//NOTE request->all is not safe
}
use updateOrCreate() for in case user does not have a profile.
I always name my routes:
Route::post('profile/edit/{id}', [UserController::class, 'update'])->name('user.update')-> middleware('auth')
Then form action looks like this:
<form method="POST" action="{{route('user.update', ['id' =>$profil->id]) }}"
This way 'id' defined in route will be easier to be identified.
Naming routes and using route() may save you some headaches when moving to production.

Delete route not getting any data Laravel 6.X

I tried changing the routes and using a specific name and several things in the action attribute but there is no way the data doesn't appear when I use the form for the delete and the dd() function on my delete route
here is what the dd shows me, no info at all
My routes:
Route::get('/home/Collections', 'CollectionController#index')->name('collection.index');
Route::get('/home/Collections/{Collection}', 'CollectionController#show')->name('collection.show');
Route::get('/home/Collections/{Collection}/edit', 'CollectionController#edit')->name('collection.edit');
Route::put('/home/Collections/{Collection}', 'CollectionController#update')->name('collection.update');
Route::get('/home/Collections/crear', 'CollectionController#create')->name('collection.create');
Route::delete('/home/Collections/{Collection}', 'CollectionController#destroy')->name('collection.destroy');
Route::post('/home/Collections', 'CollectionController#store')->name('collection.store');
My controller:
public function destroy(Collection $collection)
{
$collection->delete();
return redirect('/home'.'/Collections');
}
and my form:
#foreach ($collections as $collection)
<div id="{{$collection->id}}">
<img/>
<p>{{$collection->name}}</p>
<p>{{$collection->description}}</p>
<form action="/home/Collections/{{$collection->id}}" method="POST">
#csrf
#method('DELETE')
<input type="submit" value="ELIMINAR" class = "btn btn-outline-danger mt-2">
</form>
</div>
#endforeach
my collection model:
class Collection extends Model implements Searchable
{
protected $fillable = ['id', 'name', 'description', 'user_id', 'category_id', 'certificate_id', 'img_id'];
public function items()
{
return $this->hasMany(Item::class);
}
public function certificate()
{
return $this->hasOne(Certificate::class);
}
public function image()
{
return $this->hasOne(Image::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function getSearchResult(): SearchResult
{
$url = route('collection.show', $this->id);
return new SearchResult(
$this,
$this->name,
$url
);
}
}
Problem solved a while ago, i forgot to reply to this post.
Solved it changing the Routes URL so they dont match, it seems there was a problem with them even tho it was working like exposed on another project.

Dropdown list in Laravel is not displaying

Below my drop-down list is not displaying and I don't know where the problem is. Could it be in my SerieController? I want to create an edit/update system but I've had no success.
SerieController
public function edit($id)
{
$series = Serie::with('marks')->find($id);
return view('admin.series.edit', compact('series'));
}
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required',
'fk_mark' => 'required'
]);
$series = Serie::with('marks')->find($id);
$series->name = $request->get('name');
$series->fk_mark = $request->get('fk_mark');
$series->save();
return redirect()->route('series.index')
->with('success', 'updated successfully');
}
Mark Model
class Mark extends Model
{
protected $fillable = ['name_mark'];
public function series()
{
return $this->hasMany('App\Serie', 'fk_mark');
}
}
Serie Model
class Serie extends Model
{
protected $fillable = ['name', 'fk_mark'];
public function marks()
{
return $this->belongsTo('App\Mark', 'fk_mark');
}
}
I have another question. In my view, I have a form. Is the edit ok?
serie.index.blade
<form method="POST" action="{{ route('series.destroy', $serie) }}">
<a class="btn btn-sm btn-warning" href="{{ route('series.edit', $serie->id) }}">Editer</a>
</form>
I think it should be the other way: mark model belongsTo and Series model HasMany, no?

Comment Table Giving SQLSTATE[42S02] laravel 5.8

I am trying to make an forum where the user can post a Thread and on the bottom of the thread the user can comment to thread but when I add the commenting part to the thread it throws the SQLSTATE[42S02] Error I am trying to use Morph relation ships from laravel https://laravel.com/docs/5.8/eloquent-relationships so I can connect the thread to the corresponding thread or comment. and the final product has to be someting like Reddits one http://prntscr.com/mwvors where comment go under each other and comment can be commented on other comments.
Edit:
after php artisan migrate it updated the the migrations but give this error instead
Error
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'comments.commmentable_id' in 'where clause' (SQL: select * from `comments` where `comments`.`commmentable_id` = 1 and `comments`.`commmentable_id` is not null and `comments`.`commmentable_type` = App\Thread) (View: C:\Users\Merlijn\AppData\Roaming\Composer\Laravel Projects\Forum\resources\views\thread\single.blade.php
single.blade.php
{{--Answers/comments--}}
<div class="comment-list">
#foreach($thread->comments as $comment)
<h4>{{$comment->body}}</h4>
<lead>{{$comment->user->name}}</lead>
#endforeach
</div>
<div class="comment-form">
<form action="{{ route('threadcomment.store', $thread->id) }}" method="post" role="form">
{{csrf_field()}}
<h4>Create Comment</h4>
<div class="form-group">
<input type="text" class="form-control" name="body" id="" placeholder="Input...">
</div>
<button type="submit" class="btn btn-primary">Comment</button>
</form>
</div>
user model
public function threads(){
return $this->hasMany(Thread::class);
}
thread model
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->morphMany(Comment::class,'commmentable');
}
comment model
public function commenttable()
{
return $this->morphTo();
}
public function user()
{
return $this->belongsTo(User::class);
}
comment controller
public function addThreadComment(Request $request, Thread $thread)
{
$this->validate($request,[
'body' => 'required|min:10|max:250'
]);
$comment = new Comment();
$comment->body = $request->body;
$comment->user_id = auth()->user()->id;
$thread->comments()->save($comment);
}
web.php
Route::resource('comment','CommentController', ['only' =>['update','destroy']]);
Route::post('comment/create/{thread}','ThreadController#storeComment')->name('threadcommment.store');
there where typos in the code
public function comments()
{
return $this- >morphMany(Comment::class,'commmentable');
}
Route::post('comment/create/{thread}','ThreadController#storeComment')->name('threadcommment.store');
triple MMM instead of 2 mm

laravel 5.4 showing blank view

I am sending data from the controller to a view (this is a single page web app) but view's input fields are showing nothing. When I use console.log I got this (screenshot attached). My question is how do I show this data in an input field of view?
Controller
public function edit(Request $request){
$results = Student::where('id', '=', $request->id)->get();
return $results;
}
View
<form class="form_edit" action="" method="post" enctype="multipart/form-data">
{{csrf_field()}}
#if(isset($results))
#foreach ($results as $result)
<input type="hidden" id="id">
<input type="text" class="form-control" name="grn" value="{{$result->grn}}">
<input type="text" class="form-control" name="first_name" id="addItem" value="{{$result->first_name}}">
<input type="text" class="form-control" name="last_name" value="{{$result->last_name}}">
<input type="button" class="btn btn-danger" id="btn_delete" value="Delete">
<input type="reset" class="btn btn-default" id="btn_close" value="Cancel">
<input type="button" class="btn btn-primary" id="btn_update" value="Update">
#endforeach
#endif
</form>
you need to pass the data to view in laravel like this
public function edit(Request $request){
$results = Student::where('id', '=', $request->id)->get();
return view('your_view_folder.your_view_page', ["results" => $results]);
}
note : your not loading the view page
To answer your specific question: To pass data into a view, you must return the view, as #JYoThl quite correctly advises. But the data should be passed in as an array with key / value pairs, or you will get an error. (See Laravel 5.4 docs.)
So if, for example, the view file containing your form element were named "formView.blade.php" and it was located in the resources/views/ directory, you would modify your controller method as follows:
public function edit(Request $request)
{
$results = Student::where('id', '=', $request->id)->get();
return view('formView', ['results' => $results]);
}
Or alternatively...
public function edit(Request $request)
{
$results = Student::where('id', '=', $request->id)->get();
return view('formView')->with('results', $results);
}
$results is now available in your view.
There are a couple of things I could recommend. First of all you are searching for student by id which I would assume should return a single student and it is the primary key of student. Therefore you may want to use Student::find(); . Also you would probably want to build your queries for searching on the model or a abstract base model in which you could create basic searches that all the models that extend it could use. for instance:
abstract class BaseModel extends Eloquent{
protected $guarded = [
'id'
];
public $primaryKey = 'id';
public $incrementing = false;
public function __construct($attributes = array()) {
parent::__construct($attributes); // Eloquent
$this->id = uniqid();
return $this
}
public static function getObjectById($id){
$class = get_called_class();
$results = $class::find($id);
return $results;
}
public static function getAllObjects(){
$class = get_called_class();
return $class::all();
}
}
then your student class:
class Student extends Model
{
protected $fillable = [
'name'
];
protected $table = "student";
public $incrementing = false;
/**
* Student constructor.
* #param array $attributes
*/
public function __construct($attributes = array()) {
parent::__construct($attributes); // Eloquent
// Your construct code.
// TODO split string stuff to get the rest of the attributes.
return $this;
}
}
then your controller:
class StudentController extends Controller{
public function getStudent(Request $request){
$results = Student::getObjectById($request->id);
return response()->json([
'results' => $results
]);
}
}
Your route/web.php:
Route::get('/student', 'EnumController#getStudent');
I like using my own frontend so I may use ajax to complete the request:
<body>
<div class="container">
<div id="student-list" class="well"></div>
</div>
</body>
<script>
$.ajax({
type: "GET",
url: '/student',
success: function( data ) {
results = data.results;
console.log(results);
$.each(results, function(key, value){
$('#student-list').append('<div >' + value + '</option>');
});
}
});
</script>

Categories