Best Practice for Mass Assignment

Asked

Viewed 598 times

-2

To obtain the facilities that the framework proposes, in the specific case of saving data in a table of a database, we can use the mass assignment resource, which means, in free translation, 'mass insertion (data)'.

I followed a tutorial, and I understood that, starting from a very simple principle, the goal is reached.

My scenario consisted of a form (data source to insert), a method in a controller, a class that inherited 'Model' and, of course, a database.

But when performing the routines, I saw that the database accepted the recording, but did not fill the columns. That is, the record existed, but all blank.

I believe you have discovered the problem, but I would like to know if the solution is the best one.

At first, it was like this, while there was blank recording problem:

Table name in database: 'products'
Fields of this table: id, name, description, value, quantity. Data source form (I removed the 'fat', leaving the essential):

<form action="{{action('controllerTeste@adiciona')}}" method="post">
    <input type="hidden" name="_token" value="{{{csrf_token()}}}"/>
    <input name="namNome"/>
    <input name="namDescricao"/>
    <input name="namValor"/>
    <input name="namQuantidade" />
    <button type="submit">Salvar</button>
</form>

To reinforce understanding, above, the field with the attribute 'Hidden' is necessary so that there is no impediment to recording in the table.

The method that triggered the recording:

public function adiciona(){
        $params = Request::all();
        $produto = new Produto ($params);
        $produto->save();
        return redirect()->action('controllerTeste@lista')->withInput();
    }//adiciona

The class that inherits 'model':

<?php
namespace tempo;
use Illuminate\Database\Eloquent\Model;
class Produto extends Model
{
    protected  $table = "produtos";
    public $timestamps = false;
    protected $fillable = array('nome','descricao','valor','quantidade');
}
?>

From the perceived error, I began to imagine how Laravel could know, from what is written in the controller, how to associate each data that came from the form to the correct column in the database.

The variable $fillable, in the Product class, was clear, but the arrival of the data came from the controller, through the variable $params, which said nothing in relation to which field of the form and in which order it related to $fillable.

It was at this point that I 'suspected' the names of the fields in the form. For my convenience of separating attribute names, all fields belonging to 'name' would start with 'nam' and all id attributes would have identifiers starting with 'id' in the same way.

I then changed the names of the form fields to match exactly the names of the columns in the database.

Then it all worked out.

Then I asked myself, but will I be forced to put names on forms always under this rule? There would not be a kind of 'alias' for each form field that could be translated into the name of the target table columns?

I searched the web and, after some research, I found a code that worked.

To apply it, I returned the form names to my traditional way of writing them, and rewrote the method in the controller to 'translate' the form names to the names of the target table columns.

The controller method looks like this:

 public function adiciona(){
    $produto = Produto::create(array(
      'nome' =>Request::input('namNome'),
      'descricao'  => Request::input('namDescricao'),
      'valor'   => Request::input('namValor'),
      'quantidade' => Request::input('namQuantidade')));
    $produto->save();
    return redirect()->action('controllerTeste@lista')->withInput();
}//adiciona

What was replaced in the controller routine was to replace

$params = Request::all();
$produto = new Produto ($params);

for

$produto = Produto::create(array(
          'nome' =>Request::input('namNome'),
          'descricao'  => Request::input('namDescricao'),
          'valor'   => Request::input('namValor'),
          'quantidade' => Request::input('namQuantidade')));

So I repeat what is written in the title of this question: it is best practice?

1 answer

1

It is not necessary to write as much, do the following with your add method:

public function adiciona(Request $request){
    //capturar todos os dados do form
    $dadosFormulario = $request->all();
    //fazer insert
    $produto = Produto::create($dadosFormulario);
    return redirect()->action('controllerTeste@lista')->withInput();
}

In your model you need to declare your primary key, do the following:

protected $primaryKey = 'chave_primaria';
  • geekcom, doing it your way I would fall into the 'translation' problem between the names of the fields in the form and the names of the columns in the database table. Request->all() would bring all fields, but would give error when writing to the database. This is not the case?

  • It would be a mistake if your primary key has a different name than 'id', which is used by default in Eloquent, I edited the above answer, I believe this solves.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.