简体   繁体   中英

After submit nothing happens

I'm building a forum with Laravel. After clicking the submit button to create a new thread nothing happens, the user is not redirected and the thread doesn't appear in the database.

Here's my controller:

public function store(ThreadValidation $rules, $request)
{
    $thread = Thread::create([
        'user_id' => auth()->id(),
        'channel_id' => request('channel_id'),
        'title' => request('title'),
        'body' => request('body'),
    ]);

    return redirect($thread->path());
}

Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Thread extends Model
{
    protected $guarded = [];
    protected $fillable = ['title', 'body', 'user_id', 'channel_id'];

    public function creator()
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function replies()
    {
        return $this->hasMany(Reply::class);
    }

    public function addReply($reply)
    {
        $this->replies()->create($reply);
    }

    public function path()
    {
        return "/threads/{$this->channel->slug}/{$this->id}";
    }

    public function channel()
    {
       return $this->belongsTo(Channel::class, 'channel_id');
    }
}

Routes:

Route::get('/', function () {
        return view('welcome');
});

Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::get('threads', 'ThreadsController@index');
Route::get('threads/create', 'ThreadsController@create');
Route::get('threads/{channel}/{thread}', 'ThreadsController@show');
Route::post('/threads', 'ThreadsController@store');
Route::get('threads/{channel}', 'ThreadsController@index');
Route::post('threads/{channel}/{thread}/replies', 'RepliesController@store');

Blade:

<div class="container">
    <div class="row">
        <div class="col-md-8 offset-md-2">
            <div class="card card-default">
                <div class="card-header">Create a New Thread</div>
                <div class="card-body">
                  <form method="POST" action="/threads">
                    @csrf
                    <div class="form-group">
                      <label for="title">Add a title</label>
                      <input type="text" class="form-control" name="title" id="title">
                    </div>
                    <div class="form-group">
                      <label for="body"></label>
                      <textarea name="body" id="body" class="form-control" rows="8"></textarea> 
                    </div>
                    <button type="submit" class="btn btn-primary">Publish</button>
                  </form>
                </div>
            </div>
        </div>
    </div>
</div>

I would really appreciate if you could tell me what is wrong, because my test actually passes.

/**
 * @test
 */
public function an_authenticated_user_can_create_forum_threads()
{
    $this->withExceptionHandling()
        ->signIn();

    $thread = create('App\Models\Thread');
    $this->post('/threads', $thread->toArray());

    $this->get($thread->path())
        ->assertSee($thread->title)
        ->assertSee($thread->body);
}

Update: Form Request:

public function rules()
{
    return [
        'title' => 'required',
        'body' => 'required',
        'channel_id' => 'required||exists:channels, id',
    ];
}

Your post request does not contain a channel_id , thus this validation will fail: 'channel_id' => request('channel_id') and that is why your request will not be handled correctly.

You will have to add an input field which contains this variable, or remove it from the validation. In the order requests this will work because the url sometimes contains the id, but since this url is /threads it obviously does not contain this variable.

If you can not or do not want to force this variable you can remove the validation rule and provide a default value if the request variable is not present (however I would advice against this since it is better to require this variable if you need it anywhere else since this spares you the hassle of more checks if it is set). In order to do this you can use the Null coalescing operator , like this:

$thread = Thread::create(
    [
    'user_id' => auth()->id(),
    'channel_id' => request('channel_id') ?? "Default value",
    'title' => request('title'),
    'body' => request('body'),
    ]
);

I hope this helps you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM