Custom modules with Form Requests ... no model is created / saved ?



  • Hi, I've created a Form Request in order to set up validation of a custom module form. Let's call it CreateNewsRequest

    If some required fields are missing, redirection goes fine and it reloads the form with the errors on it. That's the expected result.

    But if all required fields are filled (therefore it should pass validation), seems that the CreateNewsRequest doesn't hit the controller. I have checked it out putting a dd($request) on the controller, and it does not trigger, as the FormRequest executes before the controller. Seems that something is going on there, but after some time, I'm starting to get lost.

    AFAIK, In the controller and in the form request, all the necessary classes are properly injected.

    Code from the CreateNewsRequest:

    <?php namespace Modules\News\Http\Requests;
    
    use Modules\Core\Internationalisation\BaseFormRequest;
    
    class CreateNewsRequest extends BaseFormRequest
    {
        protected $translationsAttributesKey = 'news::news.validation.attributes';
    
        public function rules()
        {        
            return [
                'title'     => 'required',
                'subtitle'  => 'required',
                'content'   => 'required'
            ];
        }
        
        public function translationRules()
        {
            return [
                'title'     => 'required',
                'subtitle'  => 'required',
                'content'   => 'required',
            ];
        }
    
        public function authorize()
        {
            return true;
        }
    
        public function messages()
        {
            return [
                'title.required' => trans('news::news.messages.title'),            
                'subtitle.required' => trans('news::news.messages.subtitle'),
                'content.required'  => trans('news::news.messages.content'),
            ];
        }
    
        public function translationMessages()
        {
            return [
                'title.required' => trans('news::news.messages.title'),            
                'subtitle.required' => trans('news::news.messages.subtitle'),
                'content.required'  => trans('news::news.messages.content'),
            ];
        }
    }
    

    Code from the Controller:

    <?php namespace Modules\News\Http\Controllers\Admin;
    
    use Modules\Core\Http\Controllers\Admin\AdminBaseController;
    use Modules\News\Entities\News;
    use Modules\News\Http\Requests\CreateNewsRequest;
    use Modules\News\Http\Requests\UpdateNewsRequest;
    use Modules\News\Repositories\NewsRepository;
    use Modules\Media\Repositories\FileRepository;
    use Modules\Core\Contracts\Setting;
    
    class NewsController extends AdminBaseController
    {
        /**
         * @var NewsRepository
         */
        private $news;
        /**
         * @var FileRepository
         */
        private $file;    
        /**
         * @var Setting
         */
        private $setting;
    
        public function __construct(NewsRepository $news, FileRepository $file, Setting $setting)
        {
            parent::__construct();
                    
            $this->news = $news;
            $this->file = $file;
            $this->setting = $setting;
        }
    
        /**
         * Display a listing of the resource.
         *
         * @return Response
         */
        public function index()
        {
            $news = $this->news->all();
    
            return view('news::admin.news.index', compact('news'));
        }
    
        /**
         * Show the form for creating a new resource.
         *
         * @return Response
         */
        public function create()
        {
            return view('news::admin.news.create');
        }
    
        /**
         * Store a newly created resource in storage.
         *
         * @param  Request $request
         * @return Response
         */
        public function store(CreateNewsRequest $request)
        {        
            $this->news->create($request->all());        
    
            flash(trans('core::core.messages.resource created', ['name' => trans('news::news.title.news')]));
    
            return redirect()->route('admin.news.news.index');
        }
    
        /**
         * Show the form for editing the specified resource.
         *
         * @param  News $news
         * @return Response
         */
        public function edit(News $news)
        {
        	$availableLocales = json_decode($this->setting->get('core::locales'));
        	
        	foreach ($availableLocales as $locale) {
        		$media["image_" . $locale] = $this->file->findFileByZoneForEntity('image_' . $locale, $news);
        		$media["video_poster_" . $locale] = $this->file->findFileByZoneForEntity('video_poster_' . $locale, $news);
        		$media["video_" . $locale] = $this->file->findFileByZoneForEntity('video_' . $locale, $news);
        	}
        	    	                        
            return view('news::admin.news.edit', compact('news', 'media'));
        }
    
        /**
         * Update the specified resource in storage.
         *
         * @param  News $news
         * @param  Request $request
         * @return Response
         */
        public function update(News $news, UpdateNewsRequest $request)
        {
            $this->news->update($news, $request->all());
    
            flash(trans('core::core.messages.resource updated', ['name' => trans('news::news.title.news')]));
    
            return redirect()->route('admin.news.news.index');
        }
    
        /**
         * Remove the specified resource from storage.
         *
         * @param  News $news
         * @return Response
         */
        public function destroy(News $news)
        {
            $this->news->destroy($news);
    
            flash(trans('core::core.messages.resource deleted', ['name' => trans('news::news.title.news')]));
    
            return redirect()->route('admin.news.news.index');
        }
    }
    

    And finally, code from the Resources\Lang\en\news.php:

    <?php
    
    return [
        'title' => [
            'news' => 'News',
            'create news' => 'Create a news article',
            'edit news' => 'Edit a news article',
        ],
        'button' => [
            'create news' => 'Create news article',
        ],
        'table' => [
            'title'       => 'Title',
            'subtitle'    => 'Subtitle',
            'content'     => 'Content',
            'isTop'       => 'Top news'
        ],
        'form' => [
            'title'       => 'Title',
            'subtitle'    => 'Subtitle',
            'content'     => 'Content',
            'isTop'       => 'First news in feed?'
        ],
        'messages' => [
            'title'       => 'A title is required',
            'subtitle'    => 'A subtitle is required',
            'content'     => 'Content is required'
        ],
        'validation' => [
            'attributes'    => [
                'title' => 'title',
                'subtitle' => 'subtitle',
                'content' => 'content'
            ]
        ],
    ];
    

    The view form create-fields section, quite straightforward:

    <div class="box-body">
        {!! Form::i18nInput('title', trans('news::news.form.title'), $errors, $lang) !!}
        {!! Form::i18nInput('subtitle', trans('news::news.form.subtitle'), $errors, $lang) !!}
        {!! Form::i18nTextarea('content', trans('news::news.form.content'), $errors, $lang) !!}
        {!! Form::i18nCheckbox('is_top', trans('news::news.form.isTop'), $errors, $lang) !!}
    </div>
    
    

    And finally the Entities' code:

    <?php 
    
    namespace Modules\News\Entities;
    
    use Dimsav\Translatable\Translatable;
    use Illuminate\Database\Eloquent\Model;
    use Modules\Media\Support\Traits\MediaRelation;
    
    class News extends Model
    {
        use Translatable, MediaRelation;
    
        protected $table = 'news__news';
            
        public $translatedAttributes = [
            'news_id',
            'title',
            'subtitle',
            'content'
        ];
        protected $fillable = [
            'news_id',
            'title',
            'subtitle',
            'content',
            'is_top',
        ];    
    }
    

    and

    <?php namespace Modules\News\Entities;
    
    use Illuminate\Database\Eloquent\Model;
    
    class NewsTranslation extends Model
    {	
        public $timestamps = false;
        
        protected $fillable = [
            'news_id',
            'title',
            'subtitle',
            'content',
            'is_top'
        ];
        protected $table = 'news__news_translations';
        
        public function getContentAttribute($value)
        {
            return strip_tags($value);
        }
    
    }
    

    I used the Page module as a scaffold in order to write this custom module, as well as following Laravel's 5.1 documentation, and I'm running out of ideas as I'm not seeing any possible explanation... It worked (models were saved and updated) when I used the base Request instead of my FormRequest... Now seems to catch the form errors, but even without errors it does not either validate.
    WTH I'm missing here?


  • Global Moderator

    Hey,

    I have this problem from time to time when i manually make new module resources etc.
    Most of the time it's because translations or rules setup or translationsAttributesKey.

    Let's clean up FormRequest i suppose you don't have title, subtitle, content in news__news so you can outright remove whole rules method from your FormRequest.
    Let's try to remove those and give it a go.

    So rules() method is for entity fields and translationrules() as name would suggest is for entity translations.



  • @armababy

    So that was it!!!

    Removing the rules() method didn't work:

    ReflectionException in Container.php line 556:
    Method Modules\News\Http\Requests\CreateNewsRequest::rules() does not exist
    

    but removing the content of rules() method did!

    class CreateNewsRequest extends BaseFormRequest
    {
        protected $translationsAttributesKey = 'news::news.validation.attributes';
    
        public function rules()
        {        
            return [];
        }
    
       ( ... and rest of code below)
    

    Many thanks @armababy , was losing my mind trying to find out what was going on.


  • Global Moderator

    @zedee
    Ah, okay cool, i suppose you need that method, can do simple return []; in there to be all cool n stuff :)
    Good it worked out for you :)



  • This post is deleted!

Log in to reply
 

Looks like your connection to AsgardCms was lost, please wait while we try to reconnect.