I'm wondering how would it be possible to edit two tables at the same view.
I've got 2 models which are related to eachother.
In my view I'm trying to repopulate my Form select with already inserted value in order to alter it.
Models
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Products extends Model
{
protected $table = 'products';
public $primaryKey = 'id';
public $timestamps = true;
public function user()
{
return $this->belongsTo('App\User');
}
public function material()
{
return $this->belongsTo('App\Material');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Material extends Model
{
protected $table = 'material';
public $primaryKey = 'id';
public $timestamps = true;
function products(){
return $this->hasMany('App\Products');
}
}
Controller
public function edit($id)
{
$product = Products::find($id);
return view('products.edit')->with('product', $product);
}
View(products.edit)
#extends('layouts.app')
#include('inc.messages')
#section('content')
<div class="container">
<h1>Edit</h1>
{!! Form::open(['action' => ['ProductsController#update', $product->id], 'method' => 'POST']) !!}
<div class="form-group">
{{Form::label('title', 'Title')}}
{{Form::text('title', $product->title, ['class' => 'form-control', 'placeholder' => 'Title'])}}
</div>
<div class="form-group">
{{Form::label('body', 'Body')}}
{{Form::textarea('body', $product->body, ['class' => 'form-control', 'placeholder' => 'Body text'])}}
</div>
<div class="form-group">
{!! Form::label('material', 'Material') !!}
{!! Form::select('material',dd($Materials), ['class' => 'form-control']) !!}
</div>
{{Form::hidden('_method','PUT')}}
{{Form::submit('Submit',['class' => 'btn btn-primary'] )}}
{!! Form::close() !!}
</div>
#endsection
Error output
Invalid argument supplied for foreach() (View: C:\xampp\htdocs\material\resources\views\products\edit.blade.php)
In order to repopulate a select box in Laravel you need to have possible options that a user can select and then make a select box like this:
<div class="form-group">
{!! Form::label('material', 'Material') !!}
{!! Form::select('material', ['option1', 'option2', 'option3'], null, ['class' => 'form-control']) !!}
</div>
And that option 1,2,3 array can also be called from a database.
P.S. you should use {!! !!} endings instead of {{ }} for {!! Form !!} facade.
update
in order to have the options of select box from database you need to use pluck() to get them.
Make a new function in your controller:
public function materials()
{
return DB::table('your_table')->pluck('name', 'id');
// or this ↓
return ModelName::pluck('name', 'id');
}
and then in your create and edit functions pass it through like this:
public function create($id)
{
$product = Products::find($id);
$theMaterials = $this->materials();
return view('products.create')->with('product', $product, 'materials', $materials);
}
public function edit($id)
{
$product = Products::find($id);
$theMaterials = $this->materials();
return view('products.edit')->with('product', $product, 'materials', $materials);
}
update
{!! Form::model($product, ['method' => 'PATCH', 'action' => ['ProductController#update', $product->id]]) !!}
Related
I have product and auction table. I want to add auction deadline on a specific table using form. when I submit the form the product_id in auction table is not populated and deadline shows time on which form is submited.
Here what I am trying:
I want that the create form get the deadline and store in auction table with product id so I can access it in show method of product.
create.blade.php
#extends('layouts.app')
#section('content')
<div class="mt-3" style="margin-left: 50px;">
<h2>Add new product</h2>
{!! Form::open(['action' => 'ProductsController#store', 'method' => 'POST', 'enctype' =>
'multipart/form-data', 'class' => 'w-50 py-3']) !!}
<div class="form-group">
{{Form::label('name', 'Product Name')}}
{{Form::text('name', '', ['class' => 'form-control', 'placeholder' => 'Product Name'])}}
</div>
<div class="form-group">
{{Form::label('description', 'Product Description')}}
{{Form::textarea('description', '', ['class' => 'form-control', 'placeholder' => 'Product Description', 'rows' => '4'])}}
</div>
<div class="form-group">
{!! Form::Label('category', 'Category') !!}
<select class="form-control" name="category_id">
#foreach($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
#endforeach
</select>
</div>
<div class="form-group">
{{Form::label('price', 'Product Price')}}
{{Form::number('price', '', ['class' => 'form-control', 'placeholder' => 'Product Price'])}}
</div>
<div class="form-group">
{{Form::label('deadline', 'Auction Deadline')}}
{{Form::date('{{$auction->deadline}}', '', ['class' => 'form-control'])}}
</div>
<div class="form-group">
{{Form::label('image', 'Product Image')}}
{{Form::file('image', ['class' => '', 'placeholder' => 'Product Image'])}}
</div>
{{Form::submit('Upload Product', ['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
</div>
#endsection
Product Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name', 'price', 'description', 'image',
];
public function category()
{
return $this->belongsTo('App\Category');
}
public function auction()
{
return $this->hasOne('App\Auction');
}
}
ProductsController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Product;
use App\Category;
use App\Auction;
class ProductsController extends Controller
{
public function index()
{
$categories = Category::all();
$products = Product::with('category')->latest()->paginate(3);
return view('products.index' ,compact('categories', 'products'));
}
public function create()
{
$categories = Category::all(['id', 'name']);
return view('products.create', compact('categories',$categories));
}
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'description' => 'required',
'category_id' => 'required',
'price' => 'required',
'image' => 'image|nullable',
]);
// Create Product
$product = new Product();
$product->name = request('name');
$product->description = request('description');
$product->category_id = request('category_id');
$product->price = request('price');
$product->image = $fileNameToStore;
$product->save();
$auction = new Auction();
$auction->deadline = request('deadline');
$auction->save();
return redirect('/products')->with('success', 'Product Created');
}
public function show($id)
{
$product = Product::find($id);
return view('products.show', compact('product'));
}
}
you are just creating auction, where is the relation? Delete $product->save(); line. After the $auction->save(); add this line:
$product->auction()->associate($auction);
$product->save();
Final Store method
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'description' => 'required',
'category_id' => 'required',
'price' => 'required',
'image' => 'image|nullable',
]);
// Create Product
$product = new Product();
$product->name = request('name');
$product->description = request('description');
$product->category_id = request('category_id');
$product->price = request('price');
$product->image = $fileNameToStore;
$auction = new Auction();
$auction->deadline = request('deadline');
$auction->save();
$product->auction()->associate($auction);
$product->save();
return redirect('/products')->with('success', 'Product Created');
}
Update for Irrelevant Blade problem
This line is wrong:
{{Form::date('{{$auction->deadline}}', '', ['class' => 'form-control'])}}
You are using blade close string tag in blade string tag.
Should be:
{{Form::date('deadline', '', ['class' => 'form-control'])}}
If auction variable has been passing from controller this will work
I have just created the form and action is PagesController#check and the validation is as follows:
#extends('layout')
#section('content')
<div class = "container">
{!! Form::open(['action' => 'PagesController#check' , 'method' => 'POST']) !!}
<div class = "form-group">
{{ Form::label('country','Country')}}
{{ Form::text('country','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
<div class = "form-group">
{{ Form::label('age','Age')}}
{{ Form::number('age','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
<div class = "form-group">
{{ Form::label('marks','Marks')}}
{{ Form::number('marks','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
<div class = "form-group">
{{ Form::label('description','Description')}}
{{ Form::textarea('description','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
{{ Form::submit('Submit' , ['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
</div>
#endsection
And the check() method in the PagesController is like this:
public function check(Request $request){
$this->validate($request, [
'country' => 'required',
'age' => 'required',
'marks' => 'required',
'description' => 'required'
]);
return 123;
}
Why is it then it is throwing the following error:
(2/2) ErrorException
Action App\Http\Controllers\PagesController#check not defined. (View: C:\wamp64\bin\apache\apache2.4.23\htdocs\website\resources\views\profiles.blade.php)
Here is the whole PagesController controller:
class PagesController extends Controller
{
public function home() {
return view('welcome');
}
public function about() {
$title = 'This is the about page';
return view('about')->with('title',$title);
}
public function show() {
$yomads = person::all();
return view('show')->with('yomads',$yomads);
}
public function profiles(){
return view('profiles');
}
public function check(Request $request){
$this->validate($request, [
'country' => 'required',
'age' => 'required',
'marks' => 'required',
'description' => 'required'
]);
return 123;
}
}
The error most likely has to do with the route (or lack of it) in app/Http/routes.php - check that it is properly defined there.
Furthermore, it is good practice to create custom request classes. Have a look at Form Request Validation
These can be generated with artisan:
php artisan make:request Profile
Then use it, as you were using the standard request:
public function check(ProfileRequest $request) {
[...]
I'm new with Laravel and I'm having problems while I try to detach some values from my pivot tables.
The pivot tables I'm woking with are:
excercise_workout (ejercicio_rutina) & excise_day (ejercicio_dia) (those tables have just two id's each one). The relations are ManyToMany. A workout have a lot of days and a day have a lot of excercises.
I've created these routes:
Route::resource('rutinas','RutinasController');
Route::delete('rutinas.destroyEjercicio/{id}','RutinasController#destroyEjercicio');
I have this button that is a form and call the delete:
{!! Form::open([
'method' => 'DELETE',
'action' => [ 'RutinasController#destroyEjercicio', $ejercicio->id ]
]) !!}
{!! Form::submit('Borrar Ejercicio', ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
The destroyEjercicio is the part I don't know how to hadle with:
public function destroyEjercicio($id)
{
$ejercicio = Ejercicio::findOrFail($id);
dias()->$ejercicio->detach($id);
//EXAMPLE DELETE WITH QUERY
// DB::delete('delete from toy_user where toy_id = ? AND user_id = ? AND status = 0', array($toy->id,Auth::id()));
return redirect('rutinas');
}
I recieve this error when I try to submit the delete form:
Call to undefined function App\Http\Controllers\dias()
I've tried a lot of other methods but I don't know how to do it.
I need to know the ID of the day and the ID of the excercise I want to delete. And I don't know how the past it by the post request.
UPDATE -> THIS IS THE FORM I DO NOT HAVE INPUTS TO REQUEST...
#foreach ($rutina->dias as $dia)
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-default">
<div class="panel-body">
Ejercicios para el <strong>{{ $dia->nombre }}</strong>
<hr>
#foreach ($dia->ejercicios as $ejercicio)
<ul>
<li>{{ $ejercicio->nombre }}</li>
</ul>
{!! Form::open([
'method' => 'DELETE',
'action' => [ 'RutinasController#destroyEjercicio', $ejercicio->id ]
]) !!}
{!! Form::submit('Borrar Ejercicio', ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
#endforeach
</div>
</div>
</div>
#endforeach
You need something like this:
public function destroyEjercicio($ejercicioId, $diasId)
{
$ejercicio = Ejercicio::findOrFail($ejercicioId);
$ejercicio->dias()->detach($diasId);
https://laravel.com/docs/5.1/eloquent-relationships#inserting-many-to-many-relationships
Update
How to use Request object. If you're using forms, Reuqest object will contain all form fields. Just do something like this:
public function destroyEjercicio(Request $request)
{
$ejercicioId = $request->get('ejercicioIdField');
$diasId = $request->get('diasIdField');
I solved this the following way. First I create this new route:
Route::post('rutinas.destroyEjercicio/{ejercicioId}/{diaId}', [
'as' => 'destroy',
'uses' => 'RutinasController#destroyEjercicio'
]);
You must add this array at the form:
{!! Form::open([
'method' => 'POST',
*******'route' => ['destroy', $ejercicio->id, $dia->id]******
]) !!}
{!! Form::submit('Borrar Ejercicio', ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
Then in your controller you pass the two id's that you need:
public function destroyEjercicio($ejercicioId, $diaId)
{
$ejercicio = Ejercicio::findOrFail($ejercicioId);
$ejercicio->dias()->detach($diaId);
return redirect('rutinas');
}
I had created a form like the following in my view
{!! Form::open(array('url' => 'user/posts', 'files'=> true)) !!}
<div class="form-group">
{!! Form::text('title',Input::old('title'),['class'=>'form-control', 'placeholder' => 'What is your title?']) !!}
</div>
<div class="form-group">
{!! Form::label('image', 'Your Image') !!}
{!! Form::file('image') !!}
<p class="help-block">Hey! Please don't upload over 15MB images!</p>
</div>
<div class="form-group">
{!! Form::label('caption', 'Don\'t miss to caption!') !!}
{!! Form::text('caption',Input::old('caption'),['class'=>'form-control', 'placeholder' => 'Your caption']) !!}
</div>
{!! Form::submit('Post now!',['class'=>'btn btn-info']) !!}
{!!Form::close() !!}
And I try dd() for my image from my controller but it return nulll. The following one is my Controller
public function store(PostFormRequest $request)
{
dd($request->input('image'));
$post = new Post;
}
The following one is my PostFormRequest
<?php namespace App\Http\Requests;
use Response;
use Illuminate\Foundation\Http\FormRequest;
class PostFormRequest extends FormRequest {
public function rules()
{
return [
'title' => 'required',
'image' => 'mimes:jpeg,bmp,png'
];
}
public function authorize()
{
$image = $this->image;
if(empty($image))
return true;
else
return false;
}
public function forbiddenResponse()
{
return Response::make('Sorry!',403);
}
}
When I try dd($request->input('title')); it's return string(4) "test" what I was wrong?
For files you need to use:
dd($request->file('image'));
and not
dd($request->input('image'));
Reference
Faced with the same problem. One more little thing: if you use native HTML form submit you need also set 'enctype="multipart/form-data"'. Otherwise $request->file('INPUT_NAME') returns string instead the file.
I have a many-to-many relationship between my articles and tags table, and want to require the user to input tags in the create/edit article form. I am using Ardent for my validation and have the following in my article model:
class Article extends Ardent {
use PresentableTrait;
protected $presenter = 'presenters\ArticlePresenter';
protected $fillable = ['category_id', 'title', 'description', 'content', 'published'];
public static $rules = array(
'title' => 'required',
'description' => 'required',
'content' => 'required|min:250',
'category_id' => 'exists:categories,id',
'tags' => 'required'
);
public function tags()
{
return $this->belongsToMany('Tag', 'article_tag', 'article_id', 'tag_id');
}
}
My form input:
<div class="form-group #if ($errors->has('tags')) has-error #endif">
{{ Form::label('tags', 'Tags') }}
#if(!isset($article))
{{ Form::text('tags', null, array('class' => 'form-control')) }}
#else
{{ Form::text('tags', $article->present()->implodeTags, array('class' => 'form-control')) }}
#endif
#if ($errors->has('tags')) <p class="help-block">{{ $errors->first('tags') }}</p> #endif
</div>
But the validation fails even if I enter something in the tags field, why is that?
I found the cause of this; the tags variable wasn't being passed to Ardent.
To fixed this I added the tags to the fillable variable:
protected $fillable = ['category_id', 'title', 'description', 'content', 'published', 'tags'];
Further I added the following code, explained in the Ardent readme file:
public $autoPurgeRedundantAttributes = true;
function __construct($attributes = array()) {
parent::__construct($attributes);
$this->purgeFilters[] = function($key) {
$purge = array('tags');
return ! in_array($key, $purge);
};
}
It's now possible to validate relationship data in the latest version of Administrator.