Chad Priddle
Chad Priddle

Reputation: 672

Laravel 5.4 - Duplicate row inserted

I have been using Laravel for a couple years and I'm stumped on this one. Using Laravel 5.4 with voyager. I have my own controller outside of the BREAD controller

Form:

<form method="POST" action="/admin/invites" accept-charset="UTF-8" class="form-edit-add">
<input name="_token" type="hidden" value="QgLgj5tG4RfD2CxCsqE2Qn5jcWfwQhsk5THT30vO">
<div class="panel-body">
<div class="form-group">
<label for="name">Business</label>
<input class="form-control" placeholder="Business Name" name="business_id" type="text">
</div>
<div class="form-group">
<label for="body">Referral Name</label>
<input class="form-control" placeholder="Referral Name" name="referral_name" type="text">
</div>
</div>
<input class="btn btn-primary width-100 mb-xs" type="submit" value="Save">
</form>

web routes:

Route::resource('/admin/invites',  'InviteController');

Controller:

public function store(Requests\InviteRequest $request)
{
    DB::table('invites')->insert(
        [
            'user_id' => Auth::user()->id, 
            'business_id' => $request->business_id,
            'referral_name' => $request->referral_name,
            'url_token' => str_random(16)
        ]
    );
    return redirect('/admin/invites')->with([
                    'message'    => "Successfully Added New",
                    'alert-type' => 'success',
                ]);
}

When I submit it creates 2 rows in the database. I don't have duplicate routes or controllers. My Request file is empty. I have an ID in the table that is auto increment with primary index.

Any thoughts or troubleshooting tips?

Upvotes: 1

Views: 3198

Answers (2)

Abhishek Saini
Abhishek Saini

Reputation: 680

I think the main point you are missing here is that Voyager calls its store() twice. First, through AJAX to validate the fields and then again by normal form submit to store the BREAD to the database.

Take a look at the default store() implementation in Voyager:

public function store(Request $request)
{
        $slug = $this->getSlug($request);

        $dataType = Voyager::model('DataType')->where('slug', '=', $slug)->first();

        // Check permission
        Voyager::canOrFail('add_'.$dataType->name);

        //Validate fields with ajax
        $val = $this->validateBread($request->all(), $dataType->addRows);

        if ($val->fails()) {
            return response()->json(['errors' => $val->messages()]);
        }

        if (!$request->ajax()) {
            $data = $this->insertUpdateData($request, $slug, $dataType->addRows, new $dataType->model_name());

            return redirect()
                ->route("voyager.{$dataType->slug}.edit", ['id' => $data->id])
                ->with([
                        'message'    => "Successfully Added New {$dataType->display_name_singular}",
                        'alert-type' => 'success',
                    ]);
        }
}

Notice the if (!$request->ajax()) condition, the first AJAX call would bypass that but the second call would get into it and store to the database.

So in short, you have to follow the same structure in your store() method. Perform your validations first. Then when it's time to save, put that code into the if (!$request->ajax()) condition.

Upvotes: 3

mafortis
mafortis

Reputation: 7128

your form has some issues:

<label for="name">Business</label>
<input class="form-control" placeholder="Business Name" name="business_id" type="text">

change label for to for="business_id

<label for="body">Referral Name</label>
<input class="form-control" placeholder="Referral Name" name="referral_name" 
</div>

change label for to for="referral_name

change your store method to this:

public function store(Requests\InviteRequest $request) {
      $this->validate($request, array(
        'user_id' => 'required',
        'business_id' => 'required',
        'referral_name' => 'required',
      ));

      DB::table('invites')->insert([
        'user_id' => $request->user_id,
        'business_id' => $request->business_id,
        'referral_name' => $request->referral_name,
        'url_token' => str_random(16),
        // If you don't use timestamp delete these lines below
        'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
        'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
      ]);

      return redirect('/admin/invites')->with([
                    'message'    => "Successfully Added New",
                    'alert-type' => 'success',
                ]);

    }

see if it works.

Upvotes: 0

Related Questions