2016-06-26 20 views
0

Я все еще изучаю Laravel 5 и следую за Laracasts. Я слежу за уроком https://laracasts.com/lessons/building-user-profiles, который я нашел очень полезным, однако я обнаружил некоторые незначительные изменения, необходимые для кодовой базы для внесения изменений в Laravel с момента записи видеоурока. Интересно, связана ли моя проблема с какой-то необходимой функцией или инструкцией или соглашением, которая заменила урок.Передача валидатора формы в конструктор контроллера вызывает неправильное выполнение контроллера

Когда я нажимаю ссылку «Профиль», страница четко обновляется, но я не перехожу на страницу «Показать профиль».

Это мое приложение/Http/routes.php

<?php 

/* 
|-------------------------------------------------------------------------- 
| Application Routes 
|-------------------------------------------------------------------------- 
| 
| Here is where you can register all of the routes for an application. 
| It's a breeze. Simply tell Laravel the URIs it should respond to 
| and give it the controller to call when that URI is requested. 
| 
*/ 

/** 
* All requests get passed as standard through 'web' middleware classes as definded in app/Http/Kernel.php 
*/ 

/** 
* http://fidna.dev/public 
*/ 
Route::get('/', function() { 
    return view('welcome'); 
}); 

/** 
* http://fidna.dev/public/about 
*/ 
Route::get('/about', function() { 
    $people = ['Taylor', 'Matt', 'Jeffrey']; 
    return view('pages.about', array('people' => $people)); 
}); 

Route::get('/home' ,'[email protected]'); 

Route::get('/cards', '[email protected]'); 
Route::get('/cards/{card}', '[email protected]'); 

Route::post('cards/{card}/notes', '[email protected]re'); 

Route::get('/notes/{note}/edit', '[email protected]'); 

/** 
* patch() is a synonym for save 
* The request type implies update 
*/ 
Route::patch('notes/{note}', '[email protected]'); 

Route::auth(); 

Route::get('/home', '[email protected]'); 

/** 
* Profile 
* Watch out, because /{profile} could act as a catch-all 
* Therefore, leave this route at the bottom, allowing all the other routes to be processed first 
*/ 
Route::resource('profile', 'ProfilesController', ['only' => ['show', 'edit', 'update']]); 
Route::get('/{profile}', ['as' => 'profile', 'uses' => '[email protected]']); 
/** 
* This is now implied by the routes command two lines above 
* 
Route::get('/{profile}/edit', ['as' => 'profile.edit', 'uses' => '[email protected]']); 
* 
*/ 

Мое приложение/Пользовательский/helpers.php (который зарегистрирован как autoloadable в composer.json) выглядит следующим образом:

<?php 
function link_to_profile($p_text = 'Profile') 
{ 
    /** 
    * The advantage with this first way is we are no longer hardcoding how we link to a profile 
    * You'd only have to update the named route and update that if the path to it changed 
    */ 
    return link_to_route('profile', $p_text, Auth::user()->name); 
    return link_to('/' . Auth::user()->name, $p_text); 
} 

Чтобы перейти на страницу «Показать профиль», я включил в представление link_to_profile().

приложение/HTTP/Контроллеры/ProfilesController.php выглядит следующим образом:

<?php 
namespace App\Http\Controllers; 

use App\User; 
use Illuminate\Http\Request; 
use \App\Http\Requests\ProfileForm; 
use Input; 

class ProfilesController extends Controller 
{ 

    /** 
    * Profile form requests validator class 
    * 
    * @var Http\Requests\ProfileForm 
    */ 
    protected $_profileForm = null; 

    public function __construct(ProfileForm $profileForm) 
    { 
     $this->_profileForm = $profileForm; 
    } 

    /** 
    * Action to display the specified resource 
    * 
    * @param string $username 
    * 
    * @return Response 
    */ 
    public function show($username) 
    { 
     try { 
      $user = User::with('profile.country')->whereName($username)->firstOrFail(); 
      //dd($user->toArray()); 
     } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { 
      return redirect('home'); 
     } 

     return view('profiles.show')->withUser($user); 
    } 

    /** 
    * Show the form for editing the specified resource 
    * 
    * @param integer $id 
    * 
    * @return Response 
    */ 
    public function edit($username) 
    { 
     $user = User::with('profile.country')->whereName($username)->firstOrFail(); 
     return view('profiles.edit')->withUser($user); 
    } 

    /** 
    * Edit the profile 
    * 
    * @param string $username 
    * 
    * @return Response 
    */ 
    public function update($username) 
    { 
     $user = User::with('profile.country')->whereName($username)->firstOrFail(); 
     /** 
     * Restricting input data to the values posted from the form 
     */ 
     $input = Input::only('address1', 'address2', 'city', 'postcode'); 

     $this->_profileForm->validate($input); 

     $user->profile->fill($input)->save(); 

     return view('profiles.show')->withUser($user); 

    } 

} 

Приложение/profile.php (модель) является:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Profile extends Model 
{ 

    /** 
    * The only field that can be mass-assigned is the body 
    * to avoid a Illuminate\Database\Eloquent\MassAssignmentException 
    * 
    * @var array 
    */ 
    protected $fillable = ['address1', 'address2', 'city', 'postcode']; 


    public function user() 
    { 
     return $this->belongsTo(User::class); 
    } 



    /** 
    * Relating country to profile 
    * 
    * @return type 
    */ 
    public function country() 
    { 
     return $this->belongsTo('App\Country' ,'country_id', 'id'); 
    } 

} 

Конфигурационный/app.php является :

<?php 

return [ 

    /* 
    |-------------------------------------------------------------------------- 
    | Application Environment 
    |-------------------------------------------------------------------------- 
    | 
    | This value determines the "environment" your application is currently 
    | running in. This may determine how you prefer to configure various 
    | services your application utilizes. Set this in your ".env" file. 
    | 
    */ 

    'env' => env('APP_ENV', 'production'), 

    /* 
    |-------------------------------------------------------------------------- 
    | Application Debug Mode 
    |-------------------------------------------------------------------------- 
    | 
    | When your application is in debug mode, detailed error messages with 
    | stack traces will be shown on every error that occurs within your 
    | application. If disabled, a simple generic error page is shown. 
    | 
    */ 

    'debug' => env('APP_DEBUG', false), 

    /* 
    |-------------------------------------------------------------------------- 
    | Application URL 
    |-------------------------------------------------------------------------- 
    | 
    | This URL is used by the console to properly generate URLs when using 
    | the Artisan command line tool. You should set this to the root of 
    | your application so that it is used when running Artisan tasks. 
    | 
    */ 

    'url' => env('APP_URL', 'http://localhost'), 

    /* 
    |-------------------------------------------------------------------------- 
    | Application Timezone 
    |-------------------------------------------------------------------------- 
    | 
    | Here you may specify the default timezone for your application, which 
    | will be used by the PHP date and date-time functions. We have gone 
    | ahead and set this to a sensible default for you out of the box. 
    | 
    */ 

    'timezone' => 'UTC', 

    /* 
    |-------------------------------------------------------------------------- 
    | Application Locale Configuration 
    |-------------------------------------------------------------------------- 
    | 
    | The application locale determines the default locale that will be used 
    | by the translation service provider. You are free to set this value 
    | to any of the locales which will be supported by the application. 
    | 
    */ 

    'locale' => 'en', 

    /* 
    |-------------------------------------------------------------------------- 
    | Application Fallback Locale 
    |-------------------------------------------------------------------------- 
    | 
    | The fallback locale determines the locale to use when the current one 
    | is not available. You may change the value to correspond to any of 
    | the language folders that are provided through your application. 
    | 
    */ 

    'fallback_locale' => 'en', 

    /* 
    |-------------------------------------------------------------------------- 
    | Encryption Key 
    |-------------------------------------------------------------------------- 
    | 
    | This key is used by the Illuminate encrypter service and should be set 
    | to a random, 32 character string, otherwise these encrypted strings 
    | will not be safe. Please do this before deploying an application! 
    | 
    */ 

    'key' => env('APP_KEY'), 

    'cipher' => 'AES-256-CBC', 

    /* 
    |-------------------------------------------------------------------------- 
    | Logging Configuration 
    |-------------------------------------------------------------------------- 
    | 
    | Here you may configure the log settings for your application. Out of 
    | the box, Laravel uses the Monolog PHP logging library. This gives 
    | you a variety of powerful log handlers/formatters to utilize. 
    | 
    | Available Settings: "single", "daily", "syslog", "errorlog" 
    | 
    */ 

    'log' => env('APP_LOG', 'single'), 

    /* 
    |-------------------------------------------------------------------------- 
    | Autoloaded Service Providers 
    |-------------------------------------------------------------------------- 
    | 
    | The service providers listed here will be automatically loaded on the 
    | request to your application. Feel free to add your own services to 
    | this array to grant expanded functionality to your applications. 
    | 
    */ 

    'providers' => [ 

     /* 
     * Laravel Framework Service Providers... 
     */ 
     Illuminate\Auth\AuthServiceProvider::class, 
     Illuminate\Broadcasting\BroadcastServiceProvider::class, 
     Illuminate\Bus\BusServiceProvider::class, 
     Illuminate\Cache\CacheServiceProvider::class, 
     Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, 
     Illuminate\Cookie\CookieServiceProvider::class, 
     Illuminate\Database\DatabaseServiceProvider::class, 
     Illuminate\Encryption\EncryptionServiceProvider::class, 
     Illuminate\Filesystem\FilesystemServiceProvider::class, 
     Illuminate\Foundation\Providers\FoundationServiceProvider::class, 
     Illuminate\Hashing\HashServiceProvider::class, 
     Illuminate\Mail\MailServiceProvider::class, 
     Illuminate\Pagination\PaginationServiceProvider::class, 
     Illuminate\Pipeline\PipelineServiceProvider::class, 
     Illuminate\Queue\QueueServiceProvider::class, 
     Illuminate\Redis\RedisServiceProvider::class, 
     Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, 
     Illuminate\Session\SessionServiceProvider::class, 
     Illuminate\Translation\TranslationServiceProvider::class, 
     Illuminate\Validation\ValidationServiceProvider::class, 
     Illuminate\View\ViewServiceProvider::class, 

     /* 
     * Application Service Providers... 
     */ 
     App\Providers\AppServiceProvider::class, 
     App\Providers\AuthServiceProvider::class, 
     App\Providers\EventServiceProvider::class, 
     App\Providers\RouteServiceProvider::class, 

     /** 
     * After adding illuminate/html: ~5.0 
     * @see https://laravelcollective.com/docs/5.0/html#installation 
     */ 
     Collective\Html\HtmlServiceProvider::class, 

    ], 

    /* 
    |-------------------------------------------------------------------------- 
    | Class Aliases 
    |-------------------------------------------------------------------------- 
    | 
    | This array of class aliases will be registered when this application 
    | is started. However, feel free to register as many as you wish as 
    | the aliases are "lazy" loaded so they don't hinder performance. 
    | 
    */ 

    'aliases' => [ 

     'App' => Illuminate\Support\Facades\App::class, 
     'Artisan' => Illuminate\Support\Facades\Artisan::class, 
     'Auth' => Illuminate\Support\Facades\Auth::class, 
     'Blade' => Illuminate\Support\Facades\Blade::class, 
     'Cache' => Illuminate\Support\Facades\Cache::class, 
     'Config' => Illuminate\Support\Facades\Config::class, 
     'Cookie' => Illuminate\Support\Facades\Cookie::class, 
     'Crypt' => Illuminate\Support\Facades\Crypt::class, 
     'DB' => Illuminate\Support\Facades\DB::class, 
     'Eloquent' => Illuminate\Database\Eloquent\Model::class, 
     'Event' => Illuminate\Support\Facades\Event::class, 
     'File' => Illuminate\Support\Facades\File::class, 
     'Gate' => Illuminate\Support\Facades\Gate::class, 
     'Hash' => Illuminate\Support\Facades\Hash::class, 
     'Input' => Illuminate\Support\Facades\Input::class, 
     'Lang' => Illuminate\Support\Facades\Lang::class, 
     'Log' => Illuminate\Support\Facades\Log::class, 
     'Mail' => Illuminate\Support\Facades\Mail::class, 
     'Password' => Illuminate\Support\Facades\Password::class, 
     'Queue' => Illuminate\Support\Facades\Queue::class, 
     'Redirect' => Illuminate\Support\Facades\Redirect::class, 
     'Redis' => Illuminate\Support\Facades\Redis::class, 
     'Request' => Illuminate\Support\Facades\Request::class, 
     'Response' => Illuminate\Support\Facades\Response::class, 
     'Route' => Illuminate\Support\Facades\Route::class, 
     'Schema' => Illuminate\Support\Facades\Schema::class, 
     'Session' => Illuminate\Support\Facades\Session::class, 
     'Storage' => Illuminate\Support\Facades\Storage::class, 
     'URL' => Illuminate\Support\Facades\URL::class, 
     'Validator' => Illuminate\Support\Facades\Validator::class, 
     'View' => Illuminate\Support\Facades\View::class, 

     /** 
     * After adding illuminate/html: ~5.0 
     * @see https://laravelcollective.com/docs/5.0/html#installation 
     */ 
     'Form' => 'Collective\Html\FormFacade', 
     'Html' => 'Collective\Html\HtmlFacade', 

    ], 

]; 

АРР, запрошено подтверждение формы/HTTP/Запросы/ProfileForm.php является

<?php 

namespace App\Http\Requests; 

use App\Http\Requests\Request; 

class ProfileForm extends Request 
{ 
    /** 
    * Determine if the user is authorized to make this request. 
    * 
    * @return bool 
    */ 
    public function authorize() 
    { 
     return true; 
    } 

    /** 
    * Get the validation rules that apply to the request. 
    * 
    * @return array 
    */ 
    public function rules() 
    { 
     return [ 
      'address1' => 'required|max:255', 
      'address2' => 'max:255', 
      'city' => 'required|max:255|string', 
      'postcode' => 'required' 
     ]; 
    } 
} 

ресурсов/просмотров/профили/show.blade.php является:

@extends('layouts/app') 

@section('content') 
<h1>{{ $user->name }} | <small>{{ $user->profile->location }}</small></h1> 

    <div class="address"> 

     <p> 
      {{ $user->profile->address1 }} <br> 
      {{ $user->profile->address2 }} <br> 
      {{ $user->profile->city }} <br> 
      {{ $user->profile->postcode }} <br> 
      {{ $user->profile->country->name }} 

     </p> 

    </div> 

    @if (Auth::user()->id == $user->id) 
     {{ link_to_route('profile.edit', 'Edit Your Profile', $user->name) }} 
    @endif 


@stop 

и ресурсы/виды/профили/edit.blade.php является:

@extends('layouts/app') 

@section('content') 
    <h1>Edit Profile</h1> 

    {{ Form::model($user->profile, ['route' => ['profile.update', $user->name]]) }} 

     <!-- Update request --> 
     {{ method_field('PATCH') }} 
     <!-- Update request --> 

     <!-- Necessary to circumvent TokenMismatchException which arises from recent improvements to Laravel--> 
     <!-- This supplies a posted token value --> 
     {!! csrf_field() !!} 
     <!-- Necessary to circumvent TokenMismatchException --> 

     <!-- Address Line 1 field --> 
     <div class="form-group"> 
      {{ Form::label('address1', 'Address Line 1') }} 
      {{ Form::text('address1', null, ['class' => 'form-control']) }} 
     </div> 

     <!-- Address Line 2 field --> 
     <div class="form-group"> 
      {{ Form::label('address2', 'Address Line 2') }} 
      {{ Form::text('address2', null, ['class' => 'form-control']) }} 
     </div> 

     <!-- City field --> 
     <div class="form-group"> 
      {{ Form::label('city', 'City') }} 
      {{ Form::text('city', null, ['class' => 'form-control']) }} 
     </div> 

     <!-- Postcode field --> 
     <div class="form-group"> 
      {{ Form::label('postcode', 'Post Code') }} 
      {{ Form::text('postcode', null, ['class' => 'form-control']) }} 
     </div> 


     <!-- Submit button -->   
     <div class="form-group"> 
      {{ Form::submit('Update Profile', ['class' => 'btn btn-primary']) }} 
     </div> 

      {{ $user->profile->country->name }} 


    {{ Form::close() }} 

@stop 

файлы миграции - это ванильный пакет Laravel 5 create_users_table.php и create_password_resets_table.php и созданный мной файл create_profiles_table.php, который был создан мной следующим образом:

<?php 

use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Database\Migrations\Migration; 

/** 
* Migration for profiles table 
* 
* <pre> 
* Created with artisan command: 
* 
* php artisan make:migration:schema create_profiles_table --schema="address1:string, address2:string:nullable, <br> 
* city:string, postcode:string, country:integer, location:string:nullable" 
* </pre> 
*/ 
class CreateProfilesTable extends Migration 
{ 
    /** 
    * Run the migrations. 
    * 
    * @return void 
    */ 
    public function up() 
    { 
     Schema::create('profiles', function (Blueprint $table) { 
      $table->increments('id'); 
      $table->integer('user_id'); 
      $table->string('address1'); 
      $table->string('address2')->nullable(); 
      $table->string('city'); 
      $table->string('postcode'); 
      $table->integer('country'); 
      $table->string('location')->nullable(); 
      $table->timestamps(); 
     }); 
    } 

    /** 
    * Reverse the migrations. 
    * 
    * @return void 
    */ 
    public function down() 
    { 
     Schema::drop('profiles'); 
    } 
} 

MySql создать код для таблицы профилей:

CREATE TABLE `profiles` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `user_id` INT(11) NOT NULL, 
    `address1` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `address2` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci', 
    `city` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `postcode` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `country_id` INT(11) NOT NULL, 
    `location` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci', 
    `created_at` TIMESTAMP NULL DEFAULT NULL, 
    `updated_at` TIMESTAMP NULL DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) 
COLLATE='utf8_unicode_ci' 
ENGINE=InnoDB 
AUTO_INCREMENT=2 
; 

Я могу войти и выйти из системы без проблем. Все происходит с управлением профилями, и я выделил проблему как профиль ProfilesController :: __ (ProfileForm $ profileForm). Когда я удаляю аргумент из конструктора, выполняется ProfilesController, однако я больше не имею проверки на основе формы.

Я удалил аргумент, чтобы получить меня на странице «Показать профиль», а затем повторно уведомил его один раз на странице, чтобы увидеть, как это повлияет на ссылку «Изменить профиль» в show.blade.php выше. Сайт реагирует на ошибку при ошибке «перенаправленный слишком много раз».

Я запускаю WAMPServer с PHP версии 5.5.12 и Apache версии 2.4.9

Может ли кто-нибудь помочь?

ответ

2

Проблема заключается в том, что вы никогда не должны ставить свой класс запроса формы в качестве аргумента конструктора для своего контроллера, потому что, как только этот объект будет разрешен, будет активирована проверка.

Таким образом, вы должны удалить конструктор из ProfilesController класса и изменить update метод этого контроллера, как так:

public function update($username, ProfileForm $request) 
{ 
    $user = User::with('profile.country')->whereName($username)->firstOrFail(); 
    /** 
    * Restricting input data to the values posted from the form 
    */ 
    $input = $request->only('address1', 'address2', 'city', 'postcode'); 

    $user->profile->fill($input)->save(); 

    return view('profiles.show')->withUser($user); 
} 
0
public function update(ProfileForm $request,$username) 
{ 
    $user = User::with('profile.country')->whereName($username)->firstOrFail(); 
    /** 
    * Restricting input data to the values posted from the form 
    */ 
    $input = $request->only('address1', 'address2', 'city', 'postcode'); 

    $user->profile->fill($input)->save(); 

    return view('profiles.show')->withUser($user); 

} 

Конструктор запускается автоматически при всех действиях, где, как ожидается, получить или после params.But им потребуется только обновить действие.

+0

Вы видели мой ответ? Как он отличается? –

+0

Ваш ответ верный, но я думаю, что ваш пример отображает ошибку. Переменные - это конец ваш -> публичное обновление функции ($ username, ProfileForm $ request) my -> public function update (ProfileForm $ request, $ username) –

+0

Фактически оба они должны работать –

 Смежные вопросы

  • Нет связанных вопросов^_^