How to save boolean values in laravel eloquent - php

I have made the following migration in Laravel:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class QualityCheckTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('quality_check', function (Blueprint $table) {
$table->increments('id');
$table->boolean('favicon');
$table->boolean('title');
$table->boolean('image-optimization');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('quality_check');
}
}
I have the following controller method that runs when the form in the frontEnd is submitted:
public function store(CreateArticleRequest $request) {
// $input = Request::all();
Article::create($request->all());
return redirect('articles');
}
My form looks like , so:
{!! Form::open([ 'action' => 'QualityCheckController#validateSave' , 'class'=>'quality-check-form' , 'method' => 'POST' ]) !!}
<div class="input-wrpr">
{!! Form::label('favicon', 'Favicon') !!}
{!! Form::checkbox('favicon', 'value' ); !!}
</div>
<div class="input-wrpr">
{!! Form::label('title', 'Page Title') !!}
{!! Form::checkbox('title', 'value'); !!}
</div>
<div class="input-wrpr">
{!! Form::label('image-optimization', 'Image Optimization') !!}
{!! Form::checkbox('image-optimization', 'value'); !!}
</div>
{!! Form::submit('Click Me!') !!}
{!! Form::close() !!}
So when the method runs the values of the checkboxes are saved to the database.
As of now , all entries are showing as 0 , Like so:
Now how to make it such that when the checkbox is checked , 1 is saved and when the checkbox is left unchecked the value in is left at 0 ??

When a checkbox is ticked, it's value is present in the posted data. When it is unticked, it's value is not present. This means when you do $request->all() it will contain only the checkboxes that were ticked. So in your case, if you leave all 3 checkboxes unticked, your $request->all() could yield an empty array (Assuming that no other fields are posted).
When you run Article::create($request->all()); with no checkboxes ticked you would be essentially passing it an empty set of data, which means that your database is going to be populated with the default values for the fields that you didn't provide.
Since you didn't provide a default in your migration, MySQL is going to guess what the default should be based on the field type, which in the case of a boolean will be 0. You may see some warnings/errors though.
There are loads of ways you can get this to work so that a 1 is saved when a checkbox is ticked or 0 when it is not ticked. The easiest way in your scenario would be to set the value of each checkbox to be 1 and explicitly set up default values in your migration i.e.
Migration:
$table->boolean('favicon')->default(0);
Form:
{!! Form::checkbox('title', '1'); !!}
This way, when the title checkbox is ticked, your $request->all() returns an array containing an item 'title' => '1' and this is saved in your database. All of the unticked boxes are defaulted to 0 as per your migration.
I prefer however to be more explicit when I write my method for handling the store.
$article = new Article();
$article->title = $request->has('title'); // Will set $article->title to true/false based on whether title exists in your input
// ...
$article->save();

Have you remembered to pass them in the $fillable array in the Article Model?
protected $fillable = [
'favicon',
'title',
'image-optimization'
];
and as a sidenote to the checkboxes thing. You can just make a hidden input with the same name, and make it false. That way, if the checkbox is unchecked, it will be false, but if it is checked, it will return true, as it is the last value:
<div class="input-wrpr">
{!! Form::label('title', 'Page Title') !!}
{!! Form::hidden('title', false); !!}
{!! Form::checkbox('title', 'value'); !!}
</div>

With VUE you can do it like this:
Add this line to your table
$table->boolean("image-optimization")->default(0);
Add this to your model, it will modify the value inserted in the database
protected $casts = ['image-optimization' => 'boolean'];
You don't have to modify the request with this method
Docs: https://laravel.com/docs/8.x/eloquent-mutators

You can check if checkbox is set with isset($request->favicon) or empty($request->favicon) or ->has('favicon'):
public function store(CreateArticleRequest $request) {
foreach (['favicon', 'title', 'image-optimization'] as $box) {
$request($box) = $request->has($box);
}
Article::create($request->all());
return redirect('articles');
}

Related

Laravel 5.4 update method

I am trying to update the record in the database. This is a specific element that is an element of another. Here is my code, it doesnt work :/
web.php :
Route::patch('/projects/{projectID}/{id}', 'ProjectsController#update');
Controller:
public function update($projectId, $id, CreateProjectRequest $request)
{
$page = Page::findOrFail($id);
$page->update([
'name' => $request->name,
]);
return redirect('/projects/' . $projectId);
}
HTML:
{!! Form::model($page, ['method'=>'PATCH', 'action' => ['ProjectsController#update', $project->id, $page->id]]) !!}
{!! Form::text('name',null,['class'=>'blue-inp']) !!}
{!! Form::submit('Save changes',['class'=>'btn btn-save-blue']) !!}
{!! Form::close() !!}
You need to switch the class type-hint CreateProjectRequest for just Request in your controllers update method.
The variables passed from the form input fields can then be accessed like this:
$name = $request->input('name');
More on the topic: https://laravel.com/docs/5.0/requests
You can simplify the controller method, assuming the CreateProjectRequest handled all the necessary validation and it's inputs match the inputs you want to update
Edit: I prefer to validate everything with formrequests with rules and by the time it reaches the controller, it just calls services or does stuff.
As far as naming conventions, you may not need to send the $id in the url parameter and send it within the body, in order to avoid using Request in the formrequest to validate if it exists in the database
public function update($projectId, $id, CreateProjectRequest $request)
{
$data = $request->validated();
Page::findOrFail($id)->update($data);
return redirect('/projects/' . $projectId);
}

Input field not updating in the database

I am working on a laravel 5.2 project. I am referencing category_id from Posts.
My Post model looks like
class Post extends Model
{
protected $fillable=['category_id '];
public function category(){
return $this->belongsTo('App\category');
}
}
Also, my form looks like
<div class="form-group">
{!! Form::label('category_id','Category:') !!}
{!! Form::select('category_id', $categories, '1',['class'=>'form-control']) !!}
</div>
My table data
#foreach($posts as $post)
<tr>
<td>{{$post->category['name']}}</td>
</tr>
#endforeach
The Problem is, whenever I create a new post, the category name doesn't save in the database nor does it show on the front end.
My Post Schema table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->index()->unsigned()->nullable();
});
Even when I dd() the input field for the category id on the post table, its empty. Can someone help me with this, it's making me go crazy. Thanks
I am using a resource contoller,heres my create request controller
public function store(Request $request)
{
$user=Auth::user();
$input = $request->all();
Post::create($input);
return redirect('admin/posts');
}
It is because the fillable field only is the category_id try to add the category name field on your fillable like this.
//this are the fields that is fillable
protected $fillable=['category_id','name'];
With this the category name field will be able to catch and save data.
In continuation of my comment. Your migration should look like this.
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->index()->unsigned()->nullable();
$table->string('category_name')->nullable();
});
Your model,
class Post extends Model
{
protected $fillable=['category_id','category_name'];
}
Form
<div class="form-group">
{!! Form::label('category_id','Category:') !!}
{!! Form::select('category_id', $categories, '1',['class'=>'form-control']) !!}
{!! Form::input('category_name',old('category_name'),['class'=>'form-control', 'id' => "input_name"]) !!}
</div>
and lastly your table data should look like this.
#foreach($posts as $post)
<tr>
<td>{{$post->category_name}</td>
</tr>
#endforeach
Double check your fillable and input fields if they are the same.
your given concern you only show this one.
<div class="form-group">
{!! Form::label('category_id','Category:') !!}
{!! Form::select('category_id', $categories, '1',['class'=>'form-control']) !!}
</div>
how about the other fields. We expect you already had this on your form too.
<div class="form-group">
{!! Form::label('input_name','Name:') !!}
{!! Form::input('name',old('name'),['class'=>'form-control', 'id' => "input_name"]) !!}
</div>
In your store method it should look like this
$new_post = new Post;
$new_post->category_id = Input::get(‘category_id’);
$new_post->name = Input::get(‘name’);
$new_post->save();
Just in case you’re not using the fill method of $request
In order to access your relationship's attributes, you should do:
$post->comment->name;
And try to use 'fill()' when saving
$post = new Post;
$post->fill($request->all());
$post->save();
I fixed the error using this in my form.
{!! Form::select('category_id', [''=>'choose Categories'] + $categories,['class'=>'form-control']) !!}
and this on my table.
<td>{{$post->category['name']}}</td>
Thanks all for your effort.

Selecting Tags From the UI not working

I am very new in Laravel. I'm trying to bind a property of the Model to selected values of the select tag. now, the following code can not show the selected tags.
{!! Form::label('tag_list','Tags') !!}
{!! Form::select('tag_list[]',$tags, null,['class'=>'form-control','multiple']) !!}
when I gave
{!! Form::label('tag_list','Tags') !!}
{!! Form::select('tag_list[]',$tags, [1,2,3],['class'=>'form-control','multiple']) !!}
it worked.
in model Article I have
public function getTagListAttribute()
{
return $this->tags->lists('id')->all();
}
this does not help. In some thread I found that for Laravel 5.2 pluck should work instead of list.
so I tried
public function getTagListAttribute()
{
return $this->tags()->pluck("id")->toArray();
}
I am using Laravel 5.2.39. What am I missing?
The third parameter of the select() method should contain the default value(s) of the select. You're passing null so there are no default values which will be selected automatically.So that it gives you error.
You can write your model as
public function getTagListAttribute()
{
return $this->tags->lists('id')->toArray();
}

Laravel 5.2 relationship one to one query

How i do the query to works like this example:$model->model2->attribute
<div class="form-group">
{!! Form::label('Route name') !!}
{!! Form::text('name', ( isset($climb->route->name) ? $climb->route->name : null ), array('class'=>'form-control' )) !!}
</div>
You could try using your model in the view as in a dictionary, add something like this in your controller.
$model = Model::find($id);
$model['model2'] = $model->model2;
return view('your_view', ['model' => $model]);
For this I assume you already prepared your relationship in your model, doing that for your real models should make the view work this way
<div class="form-group">
{!! Form::label('Route name') !!}
{!! Form::text('name', ( isset($climb['route']['name']) ? $climb['route']['name'] : null ), array('class'=>'form-control' )) !!}
</div>
Create a relation:
Having:
class Comment extends Model
{
/**
* Get the post that owns the comment.
*/
public function post()
{
return $this->belongsTo('App\Post');
Then thou shall call lika:
$comment = App\Comment::find(1);
echo $comment->post->title;
https://laravel.com/docs/5.2/eloquent-relationships#one-to-many
It's one many, not one one I think

How to get the id of the current model in Laravel when saving

I am working in a Laravel 5 application. I try to save a comment for a projet and I don't know how to get the $comment->project_id value.
Here is my simplified controller
public function store( CommentsFormRequest $request )
{
$comment = new Note;
$comment->message = Input::get('message');
$comment->project_id = $note->project->id;
$comment->user_id = Auth::id();
$comment->save();
return Redirect::back();
}
and here is my simplified form
{!! Form::open(array('route' => 'notes.store')) !!}
{!! Form::textarea('message', '', array('placeholder'=>'Message')) !!}
{!! Form::submit('Ajouter la note') !!}
{!! Form::close() !!}
When I try to save, I get this error:
Trying to get property of non-object
I guess it's because it tries to get the sollicitation_id of the new object wich is null. How should I get the current project_id value?
Update
Conclusion: I used an hidden field and followed #tommy 's recommendation.
My controller now uses
$note->project_id = $request->input('project_id');
and my hidden field is
{!! Form::hidden('project_id', $project->id ) !!}
Only IF the table primary column name is 'id':
$model->id;
Regardless of primary column name:
$model->getKey();
In the store method, you try to get the property project of the variable $note, which does not exist. You should pass the project ID to the store method by either adding it to the route or adding a hidden field project_id to your form.
Then, your store method should look something like this:
public function store($project_id, CommentsFormRequest $request )
{
$project = Project::find($project_id); // $project_id is transmitted over the URL
$comment = new Note; // I'd alias Note as 'Comment', or rename '$comment' to '$note' because this can be confusing in the future
$comment->project_id = $project->id;
$comment->save();
return Redirect::back();
}
If you want to add a hidden field with the project ID to the form, you can access its value by calling $request->input('project_id');
I feel the above answer is far from perfect as you're not only exposing Unique ID's to users but it's also long winded, and would fail if two users were to load the same page at the same time, instead you should do
public function store(CommentsFormRequest $request )
{
$comment = new Note([
// your fields here
]};
$comment->save();
//$comment now contains a unique ID!
return redirect($comment->id);
}
You can get last id by using insertGetId() Query Builder method
If the table has an auto-incrementing id, use the insertGetId method to insert a record and then retrieve the ID:
$id = DB::table('users')->insertGetId(
['email' => 'john#example.com', 'votes' => 0]
);
for more info check document

Categories