How to load model relationships inside an event Laravel 5.3 - laravel

I have an event for when a new article is created. On another page I am listening for this event (VueJs and Laravel Echo), and then appending the newly created article to the articles list (actually unshifting), which then updates the view reactively. However, an article has an author which is related to the users table. I keep getting error and Vue keeps crashing because the article doesn't have an author attribute. Which is because the author is a relationship. I have tried putting $this->article->load('author') in the __construct method of the event itself, and I've tried using load('author') before sending the article to the event. Neither have worked at all. How can I maintain this relationship in the event so that it will be sent in the broadcast, in turn allowing Vue to access it as a property?
Template:
<template>
<div>
<div class="article-preview-container" v-for="article in articles">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title"><a :href="article.slug">{{ article.title}}</a></h2>
</div>
<div class="panel-body">
<p class="lead">
<span class="glyphicon glyphicon-time"></span> {{ article.created_at }} |
<span class="glyphicon glyphicon-user"></span> {{ article.author.full_name }}
</p>
<div class="article-preview">
<img :src="article.main_image" :alt="article.title">
<p>{{ article.preview }}</p>
</div>
</div>
</div>
</div>
<infinite-loading :on-infinite="onInfinite" ref="infiniteLoading" spinner="spiral">
<span slot="no-more">
There are no more articles to display :(
</span>
</infinite-loading>
</div>
</template>
<script>
import InfiniteLoading from 'vue-infinite-loading';
export default {
mounted() {
Echo.channel('articles').listen('ArticleCreated', (event) => {
console.log(event.article.author);
this.articles.unshift(event.article);
});
},
data() {
return {
articles: [],
skip: 0,
};
},
methods: {
onInfinite() {
axios.get('/articles/' + this.skip).then(function (response) {
if(response.data.length > 0) {
this.articles = this.articles.concat(response.data);
this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
if(response.data.length < 5) {
this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
} else {
this.skip += 5;
}
} else {
this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
}
}.bind(this));
},
},
components: {
InfiniteLoading,
},
};
</script>
Event:
<?php
namespace App\Events;
use App\Article;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ArticleCreated implements ShouldBroadcast {
use InteractsWithSockets, SerializesModels;
public $article;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Article $article) {
$this->article = $article;
//tried $this->article->load('author')
//tried $this->article = $article->with('author')
//tried loading author using just $this->article->author
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn() {
return new Channel('articles');
}
}

Related

laravel event generate an error in real chat app

I am working on a demo for instant chat and I was able to display the number of logged in users and show their names in the "Online Users" list, but the problem is that I created a laravel event to show messages in real time, and here I get the following error message in my console: Error: Syntax error, unrecognized expression: #user=1 .
demo app details :
laravel : 5.8.*
php : ^7.1.3
redis & laravel echo & laravel echo serveur
view :
<div class="container">
<div class="row">
<div class="col-md-4">
<h2>Online Users</h2>
<hr>
<h5 id="no-online-users">No Online Users</h5>
<ul class="liste-group" id="online-users">
</ul>
</div>
</div>
<div class="row">
<div class="col-md-9 d-flex flex-column" style="height: 80vh">
<div class="h-100 bg-white mb-4 p-5" id="chat" style="overflow-y: scroll;">
#foreach($messages as $message)
#if(\Auth::user()->id == $message->user_id)
<div class="mt-4 w-50 text-white p-3 rounded float-right bg-primary">
#else
<div class="mt-4 w-50 text-black p-3 rounded float-left bg-warning">
#endif
<p>{{ $message->body }}</p>
</div>
<div class="clearfix"></div>
#endforeach
</div>
<form action="" class="d-flex">
<input type="text" id="chat-text" name="" data-url="{{ route('messages.store') }}" style="margin-right: 10px" class="col-md-9 d-flex flex-column">
<button class="btn btn-primary col-md-3">Send</button>
</form>
</div>
</div>
</div>
MessageController :
namespace App\Http\Controllers;
use App\Message;
use Illuminate\Http\Request;
class MessageController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
//index
public function index()
{
$messages = Message::all();
return view('messages.index',compact('messages'));
}
// store
public function store(Request $request)
{
//$message = auth()->user()->messages()->create($request->all());
//return $request->body;
$message = new Message();
$message->user_id = \Auth::user()->id;
$message->body = $request->body;
$message->save();
broadcast(new MessageDelivered($message))->toOthers();
}
}
the event MessageDelivered:
namespace App\Events;
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class MessageDelivered implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Message $message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('chat-group');
}
}
app.js
require('./bootstrap');
import Echo from "laravel-echo"
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
// online users :
let onlineUsersLength = 0;
window.Echo.join('online')
.here((users) => {
onlineUsersLength = users.length;
console.log(onlineUsersLength);
let userId = $('meta[name=user-id]').attr('content');
//console.log(userId);
users.forEach(function(user){
if (user.id == userId) { return; }
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
//console.log(users);
})
.joining((user) => {
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
.leaving((user) => {
$('#user='+user.id).css('display','none');
$('#no-online-users').css('display','yes');
});
// submit chat text :
$('#chat-text').keypress(function(e){
//console.log(e.which);
if(e.which == 13){
e.preventDefault();
let body = $(this).val();
let url = $(this).data('url');
let data = {
'_token': $('meta[name=csrf-token]').attr('content'),
body
}
//console.log(body);
$.ajax({
url: url,
method: 'post',
data: data,
});
}
});
window.Echo.channel('chat-group')
.listen('MessageDelivered', (e) => {
console.log('message');
});
problem :
in first user console (user id 1 in database)
in second user console (user id 2 in database)
When I refresh the page for a specific user, the error appears for the second user
I guess you have a typo here $('#user='+user.id).css('display','none')
^^^
and here $('#online-users').append('li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>'); ^^^
You may fix it
//...
users.forEach(function(user){
if (user.id == userId) { return; }
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user-'+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
//...
.joining((user) => {
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
.leaving((user) => {
$('#user-'+user.id).css('display','none');
$('#no-online-users').css('display','yes');
});
//...

Export .xslx data using Laravel Excel with parameter

I want to export data from the database to .xlsx using Laravel-Excel.
I want to pass three parameters to query the data and download into excel file.
I already search and read a few examples but still failed to make the excel file to download.
This is my blade file.
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="card">
<div class="card-header">Download Report</div>
<div class="card-body">
<div class="col-md-12" style="margin-bottom:15px">
<select class="form-control" name="plant" id="plant">
<option selected value="All">Please Select Plant</option>
#foreach($plants as $plant)
<option value="{{ $plant->id }}">{{ $plant->name }}</option>
#endforeach
</select>
</div>
<div class="col-md-12" style="">
<div class="input-group input-daterange" align="center">
<input type="text" name="from_date" id="from_date" readonly class="form-control" value="<?php echo date("Y-m-d");?>" />
<div class="input-group-addon" >To</div>
<input type="text" name="to_date" id="to_date" readonly class="form-control" value="<?php echo date("Y-m-d");?>"/>
</div>
</div>
<br>
<div class="col-md-12" align="center">
<button type="button" name="search" id="search" class="btn btn-info btn-block">Download</button>
</div>
</div>
</div>
</div>
<div class="col-md-3"></div>
</div>
</div>
<script type="text/javascript">
$(function() {
var date = new Date();
$('.input-daterange').datepicker({
todayBtn: 'linked',
format: 'yyyy-mm-dd',
autoclose: true
});
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('#search').click(function(e){
e.preventDefault();
var from_date = $('#from_date').val();
var to_date = $('#to_date').val();
var plant = $('#plant').val();
if(plant != 'All')
{
$.ajax({
url:"{{ route('export') }}",
data:{from_date:from_date, to_date:to_date, plant:plant},
dataType:"json",
})
}
else
{
alert('Please Select Plant');
}
});
});
</script>
#endsection
This is my function at the controller
public function export(Request $request)
{
return (new DetailReportDownload($request->plant,$request->from_date,$request->to_date))->download('Report Details.xlsx');
}
and This is my Export file
class DetailReportDownload implements FromQuery, WithHeadings
{
use Exportable;
protected $plant,$from,$to;
public function __construct(String $from,String $to,String $plant)
{
$this->plant = $plant;
$this->from = $from;
$this->to = $to;
}
public function headings(): array
{
return [
'plandate',
'workcentre',
'partno',
'prodduration',
'totaldowntime',
'planout',
'cumout',
];
}
public function query()
{
return DB::table('plannings')
->select(DB::raw('plandate, workcentre, partno, prodduration, coalesce(sum(downduration),0) as totaldowntime, planout, cumout'))
->join('prodstatuses', 'plannings.id', '=', 'prodstatuses.id')
->leftJoin('downtimes', 'plannings.id', '=', 'downtimes.plan_id')
->whereBetween('plandate', array($this->from, $this->to))
->where('plant_id',$this->plant)
->where('status','Finished')
->groupBy('plannings.id')
->orderBy('plannings.id');
}
}
I wanted to download excel file from parameter given in blade file.
Thanks in advance for any help
create a provider to add below code & register to app.php file
Sheet::macro('styleCells', function (Sheet $sheet, string $cellRange, array $style) {
$sheet->getDelegate()->getStyle($cellRange)->applyFromArray($style);
});
And create class to download data using parameters,
<?php
namespace App\Modules\User\Http\Exports;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
/**
* Class ExportUsers
* #package App\Exports
*/
class ExportUsers implements FromView, ShouldAutoSize, WithEvents
{
protected $plannings;
/**
* ExportUsers constructor.
* #param Collection $plannings
*/
public function __construct(Collection $plannings) {
$this->plannings = $plannings;
}
/**
* #return View
*/
public function view() : View {
return view('plannings_list', [
'plannings' => $this->plannings,
]);
}
/**
* #return array
*/
public function registerEvents() : array {
return [
AfterSheet::class => function (AfterSheet $event) {
$this->createStyle($event, 'A1:N1', 9);
$event->sheet->styleCells(
'A1:N1',
[
'font' => [
'bold' => true,
]
]
);
},
];
}
/**
* #param $event
* #param $cell
* #param $size
* #throws \PhpOffice\PhpSpreadsheet\Exception
*/
private function createStyle($event, $cell, $size) {
/** #var AfterSheet $event */
$event->sheet->getDelegate()->getStyle($cell)->getFont()->setSize($size);
}
}
add this code to controller
private function downloadCsv($exportCsvList) {
return Excel::download(new ExportUsers($exportCsvList),
'students.xlsx');
}

Send pusher notification to only 1 user in Laravel

So I'm using Laravel Event with Pusher, so far if I use public channel without any extra conditions I can get my data as notification in my blade.
The problem starts when I try to send notification to 1 user only and not everyone, I've tried PrivateChannel but I'm getting:
[Vue warn]: Error in created hook: "ReferenceError: bidId is not defined"
and
ReferenceError: bidId is not defined
Logic
Send notification to the project owner only (where his/her ID is saved in projects table)
Vue Component
<template>
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link icon-menu dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
<span class="sr-only">Notifications</span>
<i class="far fa-bell"></i>
<span class="notification-dot"></span>
</a>
<div class="dropdown-menu notifications dropdown-menu-right" aria-labelledby="navbarDropdown">
<a class="dropdown-header"><strong>You have {{bids.length}} new notifications</strong></a>
<a class="dropdown-item" v-for="bid in bids">
<div class="media">
<div class="media-left">
<i class="fa fa-fw fa-flag-checkered text-muted"></i>
</div>
<div class="media-body">
<p class="text">{{bid.message}}</p>
<span class="timestamp">{{bid.created_at}}</span>
</div>
</div>
</a>
<a class="dropdown-item more">See all notifications</a>
</div>
</li>
</template>
<script>
export default {
data() {
return{
bids:[],
}
},
created(){
this.fetchBids();
},
methods:{
fetchBids(){
// Echo.channel('bidplaced') //tested with public channel
Echo.private(`bidplaced.${bidId}`)
.listen('BidPlaced', (e) => {
this.bids.push(e.bid);
});
},
},
}
</script>
Blade
<notifications></notifications>
Controller
$bid->save();
event(new BidPlaced($bid)); //firing the event
// this is 1 way to get the user i need to receive notification
$user = $bid->project->user;
Event
class BidPlaced implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $bid;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Bid $bid)
{
$this->bid = $bid;
}
public function broadcastOn()
{
// return ['bidplaced']; //this is working as public channel
return new PrivateChannel('bidplaced.'.$this->bid->project->user_id);
}
Question
How can I get my project owner as receiver of those notifications?
Possibly a little late but hopefully this helps someone!
Controller
broadcast(new BidPlaced($user))->toOthers();
Event
use App\User
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function broadcastOn()
{
return new PrivateChannel('notification.'.$this->user->id);
}
Vue component
created() {
Echo.private('notification.'+auth.user.id)
.listen('BidPlaced', (e) => {
console.log(e);
});
},

Laravel ReactJS Post Method Not Allowed

I know there are lots of solution for this kind of problem that I'm having. But I think I have almost tried most of them and none works.
My experience with PHP Laravel is quite good but not with front-end libraries or framework such as VueJS or ReactJS. I am planning to expand my knowledge with front-end part with ReactJS.
I have created a sample project that is food ordering system. These are the tables:-
User migration table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Food migration table
public function up()
{
Schema::create('foods', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('description')->default('');
$table->boolean('in_stock')->default(1);
$table->timestamps();
});
}
Food_user migration table
public function up()
{
Schema::create('food_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('quantity');
$table->boolean('is_served')->default(0);
$table->timestamps();
});
}
My routes and related controller:-
web.php
<?php
Route::get('/', function () {
return view('welcome');
});
Route::resource('food', 'FoodController');
Route::get('/allfood', 'FoodController#index');
Route::post('/addfood', 'FoodController#create');
// Route::group(['middleware' => 'cors'], function($router){
// Route::post('/addfood', 'FoodController#create');
// });
FoodController
<?php
namespace App\Http\Controllers;
use App\Food;
use Illuminate\Http\Request;
class FoodController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return response()->json(Food::all());
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$newfood = Food::create([
'name' => request('foodname'),
'description' => request('fooddesc'),
'in_stock' => 1,
]);
return response()->json(Food::all());
}
}
I can display the seeded data well with axios
Main.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Food from './Food';
export default class Main extends Component {
constructor() {
super();
this.state = {
foods: [],
currentPage: 1,
}
}
componentDidMount() {
axios({
method: 'get',
url: 'http://localhost:8000/allfood'
})
.then(response => {
this.setState({ foods: response.data });
});
}
renderFoods() {
return this.state.foods.map(foods => {
return (
<div className="col-md-8 col-md-offset-2" key={foods.id}>
<div className="panel panel-default">
<div className="panel-heading">{ foods.name }</div>
<div className="panel-body">
{ foods.description }
</div>
</div>
</div>
);
})
}
changePage(pagenum) {
this.setState({currentPage:pagenum});
}
render() {
switch(this.state.currentPage) {
case 1:
return (
<div className="container-fluid" style={{marginTop: 50 + 'px'}}>
<div className="top-right links">
<a href="#" onClick={() =>this.changePage(2)}>Add Food</a>
<a href="#" onClick={() =>this.changePage(1)}>Order Food</a>
</div>
<div className="row text-center">
<h2>List of Menu</h2>
</div>
<div className="row">
{ this.renderFoods() }
</div>
</div>
);
break;
case 2:
return (
<div>
<div className="container-fluid" style={{marginTop: 50 + 'px'}}>
<div className="top-right links">
<a href="#" onClick={() =>this.changePage(2)}>Add Food</a>
<a href="#" onClick={() =>this.changePage(1)}>Order Food</a>
</div>
</div>
<Food/>
</div>
);
break; }
}
}
if (document.getElementById('main')) {
ReactDOM.render(<Main />, document.getElementById('main'));
}
But to add a new record (new food). Here I am stuck.
Food.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
export default class Food extends Component {
constructor() {
super();
this.state = {
newFood: {
name: '',
description: '',
instock: 0
},
foods: []
}
}
submitMenu () {
var foody = this.state.newFood;
console.log(foody);
var testpost = axios({
method: 'post',
url: 'http://localhost:8000/addfood',
data: {
name: foody.name,
description: foody.description,
in_stock: foody.instock
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
console.log(testpost);
}
handleInput(key, e) {
var state = Object.assign({}, this.state.newFood);
state[key] = e.target.value;
this.setState({newFood: state });
}
render() {
return (
<div className="container-fluid" style={{marginTop: 50 + 'px'}}>
<div className="row text-center">
<h2>Add Menu</h2>
</div>
<div className="row">
<div className="col-md-8 col-md-offset-2">
<div className="panel panel-default">
<div className="panel-body">
<form onSubmit={this.submitMenu.bind(this)} method="POST">
<div className="form-group">
<label>Food Name</label>
<input type="text" className="form-control" placeholder="Food Name" name="foodname" onChange={(e)=>this.handleInput('name',e)}/>
</div>
<div className="form-group">
<label>Food Description</label>
<textarea className="form-control" name="fooddesc" onChange={(e)=>this.handleInput('description',e)}></textarea>
</div>
<div className="checkbox">
<label>
<input type="checkbox" name="instock" value="1"/> In Stock?
</label>
</div>
<button type="submit" className="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
When I type new information in the form and submit. Laravel throws error:-
Symfony \ Component \ HttpKernel \ Exception \
MethodNotAllowedHttpException
No message
And when I check the browser's console log, here what I see:-
> Object { name: "Deep Fried Chicken", description: "Dipped with chill sauce", instock: 0 }
> Promise { <state>: "pending" }
So what is the problem here? I have tried:-
Install and configure Laravel Cors to bypass CSRF.
Create a specific Laravel Cors middleware group.
Change method from POST to GET.
Remove (comment) \App\Http\Middleware\VerifyCsrfToken::class from
kernel.php.
Try hardcoding data at axios.
I suspect my usage of axios post method is not right. Still, I just follow the documentation.
This is my first experience on full javascript front-end development. And my knowledge of javascript is very very little. I hope my question here is proper and fully explained.....
ur code is right, u just need to inform ur create method that has Request as param to get all data sent from ur axios code.
ur create would be like this and u need to return http success status code to ur client side code (201) :
for more information about http code read this article : link
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create(Request $request)
{
$newfood = Food::create([
'name' => $request->get('foodname'),
'description' => $request->get('fooddesc'),
'in_stock' => 1,
]);
//return response()->json(Food::all()); /* u don't need to return data here */
return response()->json([],201);
}

Laravel 5.2.45 - empty $errors variable in views

Problem:
The $errors variable is empty in the views. There's talk that this has been fixed in 5.2 so hopefully the problem is on my end.
Environment:
Mac OS X
Laravel 5.2.45
The Codez:
Routes.php
Route::get('/', 'AlleleController#index');
Route::get('/register', function () {
return view('auth.register');
});
Route::auth();
Route::get('/home', 'HomeController#index');
Route::get('/alleles', 'AlleleController#index');
Route::post('/allele', 'AlleleController#store');
Route::delete('/allele/{allele}', 'AlleleController#destroy');
AlleleController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Allele;
class AlleleController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
// All methods require authentication except index.
$this->middleware('auth', ['except' => ['index']]);
}
/**
* Root page.
*
* #return Response
*/
public function index() {
return view('welcome');
}
/**
* Create a new allele.
*
* #param Request $request
* #return Response
*/
public function store(Request $request) {
$allele = new Allele();
// Get all input as an array.
$input = $request->all();
// Validate input.
if ($allele->validate($input)) {
// Valid input. Write to database.
// The inserted model instance is returned.
$result = $allele::create($input);
if ($result) {
// Insert successful.
$message = array('message' => 'Data added!');
return view('home', $message);
} else {
// Insert failed. Send errors to view.
$errors = array('errors' => 'Error saving data.');
return view('home', $errors);
}
} else {
// Invalid input. Get errors.
$errors = $allele->errors();
// Send errors to view.
return view('home', $errors);
}
}
}
?>
HomeController.php:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
class HomeController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index() {
return view('home');
}
}
Model: Allele.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Allele extends Validation {
/**
* The attributes that are mass assignable.
*/
protected $fillable = ['allele'];
/**
* Validation rules.
*/
protected $rules = array (
'allele' => 'required|max:20',
);
}
Model: Validation.php
<?php
namespace App;
use Validator;
use Illuminate\Database\Eloquent\Model;
class Validation extends Model {
protected $rules = array();
protected $errors;
public function validate($input) {
// Make a new validator object.
$v = Validator::make($input, $this->rules);
// Check for failure.
if ($v->fails()) {
// Set errors and return false.
$this->errors = $v->errors();
return false;
}
// Validation passed.
return true;
}
// Retrieves the errors object.
public function errors() {
return $this->errors;
}
}
View: views/common/errors.blade.php
#if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<strong>Whoops! Something went wrong!</strong>
<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
View: views/home.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Dashboard</div>
<div class="panel-body">
You are logged in!
</div>
</div>
</div>
</div>
</div>
<!-- Create New Allele -->
<div class="panel-body">
<!-- Display Validation Errors -->
#include('common.errors')
<!-- New Allele Form -->
<form action="{{ url('allele') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- Allele Name -->
<div class="form-group">
<label for="allele-name" class="col-sm-3 control-label">Allele</label>
<div class="col-sm-6">
<input type="text" name="allele" id="allele-name" class="form-control">
</div>
</div>
<!-- Add Allele Button -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-plus"></i> Add Allele
</button>
</div>
</div>
</form>
</div>
#endsection
All validation methods should be placed inside web middleware . I do not see any other error. Replace your route.php like this.
Route::group(['middleware' => ['web']], function ()
{
Route::get('/', 'AlleleController#index');
Route::get('/register', function () {
return view('auth.register');
});
Route::auth();
Route::get('/home', 'HomeController#index');
Route::get('/alleles', 'AlleleController#index');
Route::post('/allele', 'AlleleController#store');
Route::delete('/allele/{allele}', 'AlleleController#destroy');
});

Resources