I made a StatusController to change the status. I have Banner model and Page model.
My StatusController Looks like:
namespace App\Http\Controllers;
use App\Banner;
use App\Page;
use Illuminate\Http\Request;
class StatusController extends Controller
{
public function changeStatus($modelName, $id)
{
$model = $modelName::select('id','status')->whereId($id)->first();
if($model->status == 1)
{
$model->status = 0;
} else {
$model->status = 1;
}
$model->update();
$notification = [
'message' => 'Updated Successfully!',
'alert-type' => 'success'
];
return back()->with($notification);
}
}
My Web.php is :
Route::post('status/{modelName}/{status}', 'StatusController#changeStatus')->name('status');
My View looks Like this:
<form action="{{route('status',['model' => 'Page', 'status' => $page->id])}}" method="POST">
{{csrf_field()}}
<button title="Turn OFF" class="btn btn-xs btn-default">
<i class="fa
#if($page->status==1)
status-active
fa-toggle-on
#else
status-inactive
fa-toggle-off
#endif
fa-2x"></i>
</button>
I want to change my status when I click status icon. But when i click it. It shows an error.
FatalThrowableError in StatusController.php line 15:
Class 'Page' not found
When I tried dd($modelName) it shows Page. What's going wrong
Also, Please tell me if there is any other better idea to change status. For all my models.
Even though you have the use App\Page; statement at the top, php will have issues calling functions on a class when all you have is the class string. Page is different from 'Page'. Instead, you need to use call_user_func:
$model = call_user_func("App\\$modelName::select", ['id','status'])
->whereId($id)
->first();
Related
I am creating a backend page that i want to use to manage employee data (with laravel 5.8). I Added a link on a sidemenu blade that points to the employee overview page.
Link:
<li class="nav-item">
<a href="{{ action('Profiles\Controllers\EmployeeController#index') }}"
class="nav-link {{ Request::is('admin') ? 'active' : null }}">
<i class="fas fa-user"></i> Employees
</a>
</li>
I also made a controller to fetch the data that i want to display, currently with dd() in the function.
class EmployeeController extends Controller
{
public $model = CustomerLogin::class;
protected $views = 'WebshopCustomers::customerslogins ';
static $routes = ['index', 'create', 'store', 'edit', 'update', 'destroy'];
protected $datatableSelect = 'customer_logins';
protected $datatableRelations = ['roles', 'permissions'];
protected $datatableTrashed = true;
protected $datatableRawColumns = ['email', 'deleted_at'];
public function baseBreadcrumbs()
{
return [
['name' => 'Gebruikersbeheer']
];
}
public function index()
{
dd('test_index');
}
}
After a reloaded the page shows the following error:
ErrorException (E_ERROR):
Action App\Modules\Profiles\Controllers\EmployeeController#index not defined.
(View: C:\xampp\htdocs\shopname\app\Modules\Backend\Views\partials\sidebar-default.blade.php)
Route:
I googled this error and read advice to check if the route to the function existed (it didnt) so i added that.
Route::get('/', 'EmployeeController#index')->name('employeeprofiles.index');
Changing the value of $namespace to null in the RouteServiceProvider was also mentioned, setting it to null did not change the current behavior of my code.
How can i correct this, what other things can i check?
in Laravel 5.8 in the RouteServiceProvider the namespace for routes was pointed to:
App/Http/Controllers
in the new Laravel I think they removed it.
Now for your problem, you should check where is the namespace from RouteServiceProvider pointing too, and then adding extra 'directories' on it; e.g
Route::get('/',
'App\Modules\Profiles\Controllers#index')->name('employeeprofiles.index');
I want a user to delete a product when he clicks unlike button but I'm getting an error 404 url not found, but I have the url.
If I put dd($product) before $like = Like::findOrFail($product);
it displays the id(4) but if I put dd($like), then it throws an error 404. How can I make this function work?.
Controller
public function destroy($product)
{
$like = Like::findOrFail($product);
dd($like);
$like->delete();
return 'done';
}
Blade
<a class="remove" href="{{ route('product.unlike', ['product' => $product->id]) }}" > Unlike </a>
Route
Route::get('product/{product}/unlike', ['as' => 'product.unlike', 'uses' => 'LikeController#destroy']);
Like.php
class Like extends Model
{
use SoftDeletes;
protected $table = 'likeables';
protected $fillable = [
'user_id',
'product_id',
'likeable_id',
'likeable_type',
];
public function products()
{
return $this->morphedByMany('App\Product', 'likeable');
}
delete request should be post request not get
web.php
Route::delete('product/{product}/unlike','LikeController#destroy')->name('product.unlike');
blade.php
<form action="{{ route('product.unlike',[$product->id]) }}" method="post">
#csrf
#method('DELETE')
<button type="submit" class="remove"> Unlike </button>
</form>
controller
use App\Product;
...
public function destroy(Product $product) {
$product->delete();
return 'done';
}
Hope this helps!
Detach the Products corresponding to the like.
public function destroy($product)
{
Like::where('product_id', $product)
->where('user_id', auth()->user()->id)
->delete();
return 'done';
}
findOrFail will throw an exception which will cause the 404 when it can't find a record. You are using SoftDeletes so the record can exist in the database but doesn't mean that it hasn't been 'soft deleted'. If it has been soft deleted the scope will make it act like it isn't there.
Check your record with id == 4 to see if it has a deleted_at column with a value. If it does, it was deleted (soft deleted). You will have to adjust your query to be able to retrieve soft deleted records.
Laravel 6.x Docs - Eloquent - Soft Deletes - Querying Soft Deleted Models
Strange issue here! My return code within the controller is as follows:
return back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
And then I display the errors within blade:
#if ($errors->any())
<article class="message is-danger">
<div class="message-body">
<ul>
#foreach ($errors->all() as $error)
<li>{!! $error !!}</li>
#endforeach
</ul>
</div>
</article>
#endif
However this doesn't appear to be working at all, $errors is empty for some reason, however this works fine from another controller!
This is the method where this works, I have included the use classes.
namespace App\Http\Controllers;
use App\Pages;
use App\PlannerStatus;
use App\SubPages;
use App\VehicleMake;
use App\Website;
use App\WebsiteRedirects;
use Illuminate\Http\Request;
use Redirect;
class RedirectsController extends Controller
{
public function store(Request $request, Website $website)
{
$error = [ 'test' => 'test error' ];
if (!empty($error)) {
return back()->withErrors($error)->withInput();
}
return back();
}
}
And this is the controller where this does NOT work, as you can see they are the same, more or less!
namespace App\Http\Controllers;
use App\ResultsText;
use App\VehicleMake;
use App\VehicleModel;
use App\VehicleType;
use App\SearchPath;
use App\Website;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\MessageBag;
use Redirect;
class ResultsTextController extends Controller
{
public function update(Website $website, ResultsText $resultsText, Request $request)
{
$data = request()->except(['_token','id']);
$result = ResultsText::where('id', $resultsText->id)->update($data);
if (!$result) {
return back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
}
return Redirect::action('ResultsTextController#index', $website);
}
}
Also here are my Routes, just so you can see they are pretty much identical:
Route::prefix('/redirects')->group(function () {
Route::get('/', 'RedirectsController#index')->middleware('SettingStatus:redirect');
Route::patch('/update', 'RedirectsController#update');
});
Route::prefix('/results-text')->group(function () {
Route::post('{resultsText}/update', 'ResultsTextController#update');
});
Inside your blade try this
#if ($errors->any())
<article class="message is-danger">
<div class="message-body">
<ul>
#foreach ($errors as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
</article>
#endif
It's easily overlooked in your question. The problem is not what it seems. You will probably find it funny why it doesn't work.
Replace
return back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
with
return redirect()->back()->withErrors([ 'not_updated' => 'Unable to update record or no changes made' ]);
I'm new to laravel, axios and vue and I used this tutorial to help make a ToDo list:
I want to tweak the basic tutorial by allowing different users to store and view their tasks. I added new user registration and login, but each user would see everyone's list, not only theirs. So I made a one to many relationship between the User and Task model and added these methods to the models:
class User extends Authenticatable
{
...
public function tasks()
{
return $this->hasMany('App\Task');
}
}
class Task extends Model
{
...
public function user()
{
return $this->belongsTo('App\User');
}
}
I updated TaskController.php and TaskList.vue to display only the active user's tasks, but now in the view no list appears and new tasks can't be added.
Here is the code for the two. Everything is the same as the tutorial, except I commented next to the parts that I added:
<?php
namespace App\Http\Controllers;
use App\Task;
use Illuminate\Http\Request;
class TaskController extends Controller
{
$user = Auth::user(); //Added by me
public function index()
{
return Task::latest()->where('user_id', $user->id)->get(); //Added by me,
//this query returns whats expected in php artisan tinker
//was previously return Task::latest()->get();
//I also tried this: return $this->user->tasks->toJSON()
}
public function store(Request $request)
{
$this->validate($request, [
'body' => 'required|max:500'
]);
return Task::create([
'body' => request('body'),
'user_id' => $user->id //Added by me
]);
}
public function destroy($id)
{
$task = Task::findOrFail($id);
$task->delete();
return 204;
}
}
In TaskList.vue
<template>
<div class='row'>
<h1>My Tasks</h1>
<h4>New Task</h4>
<form action="#" #submit.prevent="createTask()">
<div class="input-group">
<input v-model="task.body" type="text" name="body" class="form-control" autofocus>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">New Task</button>
</span>
</div>
</form>
<h4>All Tasks</h4>
<ul class="list-group">
<li v-if='list.length === 0'>There are no tasks yet!</li>
<li class="list-group-item" v-for="(task, index) in list">
{{ task.body }}
<button #click="deleteTask(task.id)" class="btn btn-danger btn-xs pull-right">Delete</button>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
task: {
id: '',
body: '',
user_id: '' ///Added by me
}
};
},
created() {
this.fetchTaskList();
},
methods: {
fetchTaskList() {
axios.get('api/tasks').then((res) => {
this.list = res.data;
});
},
createTask() {
axios.post('api/tasks', this.task)
.then((res) => {
this.task.body = '';
this.task.user_id = ''; ///added by me
this.edit = false;
this.fetchTaskList();
})
.catch((err) => console.error(err));
},
deleteTask(id) {
axios.delete('api/tasks/' + id)
.then((res) => {
this.fetchTaskList()
})
.catch((err) => console.error(err));
},
}
}
</script>
</script>
The app worked until I added the few lines mentioned above. Now nothing shows in the display and no new tasks can be added. I am new to laravel and totally new to axios and vue, but to me it seems like what I added should work. There are no error messages when I run it, it just doesn't produce what I want.
I have implemented a like/favourite function in my application, where a user can favourite a Charity - this is then stored in a table in my database - which is working reasonably well.
How would I go about outputting the users favourites list to them on their profile page?
Profile View (Where I want to output):
<div class="favourite_section">
<div class="col-md-5 pull-right">
<div class="panel panel-default">
<div class="panel-heading">
Edit
<h3 class="panel-title"> Your Favourites </h3>
</div>
<div class="panel-body">
<!-- Output users' favourites. -->
<h4> </h4>
</div>
</div>
</div>
Like Controller:
<?php
namespace App\Http\Controllers;
use App\Like;
use Illuminate\Support\Facades\Auth;
class LikeController extends Controller
{
public function likePost($id)
{
$this->handleLike('App\charity', $id);
return redirect()->back();
}
public function handleLike($type, $id)
{
$existing_like = Like::withTrashed()->whereCharityImg($type)->whereCharityDesc($type)->whereCharityName($type)->whereCharityId($id)->whereUserId(Auth::id())->whereId($id)->first();
if (is_null($existing_like))
{
Like::create([
'id' => $id,
'user_id' => Auth::id(),
'charity_id' => $id,
'charity_name' => $type,
'charity_desc' => $type,
'charity_img' => $type
]);
}
else
{
if (is_null($existing_like->deleted_at))
{
$existing_like->delete();
}
else
{
$existing_like->restore();
}
}
}
}
You're able to retrieve the currently logged in user with Laravel's Authentication Facade or, if you prefer using helpers, auth()->user(). In a similar vein, you can do Auth::id() to skip the object and get the user's id directly. In your controller, you'll want to query the Like model where the user_id of the Like is equal to the user id of the logged in user:
$likes = Like::whereUserId(Auth::id())->get();
This will return a collection of likes which should be passed to the view from the controller, like so:
return view('profile', compact('likes'));
Replace 'profile' with whatever the view file for the profile page is. Then in the Blade template, you'll have access to a $likes variable, which you can iterate over:
#foreach($likes as $like)
// Do what you want with each like
#endforeach
Your situation is called many to many relationship.
Laravel docs
Laravel makes it easy. You should write a method to you User model.
Something like:
public function favourites() {
return $this->belongsToMany('App\Charity', '[Like model table name]', 'user_id', 'charity_id');
}
You then can use it like: $user->favourites and it will return collection of favourite charities.
You can read docs if you want.