为什么我不能使用 Laravel 将带有用户 ID 字段的 post 保存到数据库中?

Why can I not save a post with a user ID field to a database using Laravel?

我正在使用 Laravel 5 开发一个管理风格的应用程序,它有一个 login/logout 功能和一个供用户创建自己的帖子的工具(在这个例子中他们被称为 'bookings').我希望每个用户都能够创建自己独有的预订 - 即只有在使用用户名和密码登录时才可见。为了实现这一点,我在 'bookings' table(存储所有预订)中为 user_id 创建了一个列。当登录用户创建预订时,我希望 his/her 自己的用户 ID 存储在 user_id 列中。因此,目前我将 user_id(使用 auth()->user() 确定)作为路由 (url) 中的附加参数传递给 'bookings.store' 函数。但是,我在提交表单时不断收到消息:"No query results for model [App\Booking]",而不是被重定向回预订页面并按预期保存新预订。

这是我的一些代码: // BookingsController.php:

<?php

namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redirect;

use Illuminate\Http\Request;

use View;

use App\Model;

use App\User;

use App\Booking;

use App\BookingItem;

use App\Http\Controllers\Validator;

use Input;

class BookingsController extends Controller
{

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $bookings = \App\Booking::all();
        return View::make('bookings.index')->with('bookings', $bookings);
            // $user = auth()->user()->id;
            // $bookings = auth()->user()->bookings()->get();
            // return view('bookings.index')->with('bookings', $bookings);

    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $user = auth()->user();
        return View::make('bookings.create')->with('user', $user);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request, $user_id)
    {
        // define rules
        $rules = [
            'name' => 'between:2,255',
        ];

         $this->validate($request, [
            'name' => 'required|unique:bookings|max:255',
        ]);


        $name = $request->get('name');
        $description = $request->get('description');
        $booking->name = $name;
        $booking->user_id = $user_id;
        $booking->description = $description;
        $booking->save();
        return Redirect::route('bookings.index')->withMessage('Booking Was Created');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $booking = \App\Booking::findorFail($id);
        $items = $booking->BookingItems()->get();        
        return View::make('bookings.show')
        ->withBooking($booking) // will allow us to see our bookings, by id.
        ->withItems($items);

    }
}

?>

// Create.blade.php

@extends('layouts.main')
@section('content')
<div class="container">
    <div class="row">
        <div class="small-6 columns">
            <div class="panel panel-default">
                <div class="panel-heading"><h2>Add a new booking</h2></div>
                <div class="panel-body">
                    {{ var_dump($user->id) }}
                    <form class="form-horizontal" role="form" method="POST" action="{{ route('bookings.store', $user->id) }}">
                        <input name="_method" type="hidden" value="PUT">
                        {!! csrf_field() !!}
                        @include('bookings.partials._form');
                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    <i class="fa fa-btn fa-briefcase"></i>Add Booking
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

@stop

// web.php(我的路线)

    Route::get('/', 'BookingsController@index');
    Route::resource('bookings', 'BookingsController');
    Route::resource('bookings.items', 'BookingItemController', ['except' => ['index', 'show']]);
    Route::resource('agents', 'UsersController');
    Route::get('/bookings/{bookings}/items/{items}/complete', ['as' => 'bookings.items.complete', 'uses' => 'BookingItemController@complete']);
    Auth::routes();

Route::get('/home', 'HomeController@index');
Route::get('/logout', function(){
    Auth::logout();
    return Redirect::route('bookings.index')->withErrors('You Are Logged Out!');
});
Route::post('/bookings/{id}', ['uses' => 'BookingsController@store', 'as' => 'bookings.store']);

我的预订 table 包含以下列:

id (pk) user_id(假的) 姓名 描述 created_at updated_at

如果有人有任何建议或可以提供帮助,那就太好了。目前,我认为它可能默认为 show 路线。

此致,

罗伯特 英国伦敦

当前路线:

+--------+-----------+--------------------------------------------+-------------------------+------------------------------------------------------------------------+--------------+
| Domain | Method    | URI                                        | Name                    | Action                                                                 | Middleware   |
+--------+-----------+--------------------------------------------+-------------------------+------------------------------------------------------------------------+--------------+
|        | GET|HEAD  | /                                          |                         | App\Http\Controllers\BookingsController@index                          | web          |
|        | GET|HEAD  | agents                                     | agents.index            | App\Http\Controllers\UsersController@index                             | web          |
|        | POST      | agents                                     | agents.store            | App\Http\Controllers\UsersController@store                             | web          |
|        | GET|HEAD  | agents/create                              | agents.create           | App\Http\Controllers\UsersController@create                            | web          |
|        | GET|HEAD  | agents/{agent}                             | agents.show             | App\Http\Controllers\UsersController@show                              | web          |
|        | DELETE    | agents/{agent}                             | agents.destroy          | App\Http\Controllers\UsersController@destroy                           | web          |
|        | PUT|PATCH | agents/{agent}                             | agents.update           | App\Http\Controllers\UsersController@update                            | web          |
|        | GET|HEAD  | agents/{agent}/edit                        | agents.edit             | App\Http\Controllers\UsersController@edit                              | web          |
|        | GET|HEAD  | api/user                                   |                         | Closure                                                                | api,auth:api |
|        | POST      | bookings                                   | bookings.store          | App\Http\Controllers\BookingsController@store                          | web          |
|        | GET|HEAD  | bookings                                   | bookings.index          | App\Http\Controllers\BookingsController@index                          | web          |
|        | GET|HEAD  | bookings/create                            | bookings.create         | App\Http\Controllers\BookingsController@create                         | web          |
|        | GET|HEAD  | bookings/{bookings}/items/{items}/complete | bookings.items.complete | App\Http\Controllers\BookingItemController@complete                    | web          |
|        | DELETE    | bookings/{booking}                         | bookings.destroy        | App\Http\Controllers\BookingsController@destroy                        | web          |
|        | PUT|PATCH | bookings/{booking}                         | bookings.update         | App\Http\Controllers\BookingsController@update                         | web          |
|        | GET|HEAD  | bookings/{booking}                         | bookings.show           | App\Http\Controllers\BookingsController@show                           | web          |
|        | GET|HEAD  | bookings/{booking}/edit                    | bookings.edit           | App\Http\Controllers\BookingsController@edit                           | web          |
|        | POST      | bookings/{booking}/items                   | bookings.items.store    | App\Http\Controllers\BookingItemController@store                       | web          |
|        | GET|HEAD  | bookings/{booking}/items/create            | bookings.items.create   | App\Http\Controllers\BookingItemController@create                      | web          |
|        | DELETE    | bookings/{booking}/items/{item}            | bookings.items.destroy  | App\Http\Controllers\BookingItemController@destroy                     | web          |
|        | PUT|PATCH | bookings/{booking}/items/{item}            | bookings.items.update   | App\Http\Controllers\BookingItemController@update                      | web          |
|        | GET|HEAD  | bookings/{booking}/items/{item}/edit       | bookings.items.edit     | App\Http\Controllers\BookingItemController@edit                        | web          |
|        | POST      | bookings/{id}                              | bookings.store          | App\Http\Controllers\BookingsController@store                          | web          |
|        | GET|HEAD  | home                                       |                         | App\Http\Controllers\HomeController@index                              | web,auth     |
|        | GET|HEAD  | login                                      | login                   | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest    |
|        | POST      | login                                      |                         | App\Http\Controllers\Auth\LoginController@login                        | web,guest    |
|        | POST      | logout                                     |                         | App\Http\Controllers\Auth\LoginController@logout                       | web          |
|        | GET|HEAD  | logout                                     |                         | Closure                                                                | web          |
|        | POST      | password/email                             |                         | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest    |
|        | GET|HEAD  | password/reset                             |                         | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest    |
|        | POST      | password/reset                             |                         | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest    |
|        | GET|HEAD  | password/reset/{token}                     |                         | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest    |
|        | GET|HEAD  | register                                   |                         | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
|        | POST      | register                                   |                         | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |
+--------+-----------+--------------------------------------------+-------------------------+------------------------------------------------------------------------+--------------+

为什么不在创建过程中获取经过身份验证的用户 ID 而不是通过表单发送它?这也可能是一个巨大的安全问题,因为用户可以修改页面的 HTML 并使用不同的用户 ID 提交预订。

这是一个解决方法:

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 *
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    // define rules
    $rules = [
        'name' => 'between:2,255',
    ];
    $this->validate($request, [
        'name' => 'required|unique:bookings|max:255',
    ]);

    $booking = new Booking();

    $booking->name = $request->name;
    $booking->user_id = auth()->id();
    $booking->description = $request->description;
    $booking->save();

    return Redirect::route('bookings.index')->withMessage('Booking Was Created');
}

编辑:

你在这里有这条路线:

Route::post('/bookings/{id}', ['uses' => 'BookingsController@store', 'as' => 'bookings.store']);

但是在您的 HTML 表单中您发起了一个 PUT 请求,而它应该只是一个标准的 POST:

<input name="_method" type="hidden" value="PUT">

您需要为路线命名,因为 bookings.store 已经在 Route::resource('bookings', 'BookingsController');

中定义

我建议从资源中排除此资源并使用可选的 {id?} 参数定义您的 bookings.store 您可以检查是否存在,以便您可以存储用户的预订或基于存储方法中存在该参数。

同样按照@Steve Bauman 的建议,从您的表单中删除 <input name="_method" type="hidden" value="PUT"> 因为它正在访问您的 bookings.update 方法。

所有的组合应该如下:

    Route::get('/', 'BookingsController@index');

    Route::resource('bookings', 'BookingsController', ['excep'=> ['store']]);
    Route::post('/bookings/{id?}', ['uses' => 'BookingsController@store', 'as' => 'bookings.store']);

    Route::resource('bookings.items', 'BookingItemController', ['except' => ['index', 'show']]);
    Route::resource('agents', 'UsersController');
    Route::get('/bookings/{bookings}/items/{items}/complete', ['as' => 'bookings.items.complete', 'uses' => 'BookingItemController@complete']);
    Auth::routes();

Route::get('/home', 'HomeController@index');
Route::get('/logout', function(){
    Auth::logout();
    return Redirect::route('bookings.index')->withErrors('You Are Logged Out!');
});
Route::post('/bookings/{id}', ['uses' => 'BookingsController@store', 'as' => 'bookings.store']);

然后在控制器中的存储方法中:

public function store(Request $request, $user_id = null)
{
    // define rules
    $rules = [
        'name' => 'between:2,255',
    ];

     $this->validate($request, [
        'name' => 'required|unique:bookings|max:255',
    ]);

    $booking->name = $request->get('name');
    $booking->description = $request->get('description');

    $booking->user_id = $user_id;

    $booking->save();

    return Redirect::route('bookings.index')->withMessage('Booking Was Created');
}

这样,如果有 id,它将为您处理工作,如果没有,它将是 null