how to pass and insert id in controller store laravel - php

in view
<form action="{{route('memberPost', $courses->id)}}" method="POST">
#csrf
<button type="submit" class="btn clever-btn mb-30 w-100">Ikut course</button>
</form>
in controller
public function detail_courses($slug){
$courses = Course::where('slug', $slug)->first();
return view('single-courses', compact('courses','id_courses'));
}
public function memberPost(Request $request, $id){
$courses = Course::where('id', $id)->first();
$id_courses = $courses->id;
$member = Member::create([
'user_id' => auth()->user()->id,
'course_id' => $id_courses
]);
return redirect()->route('detail_courses');
}
in route
Route::group(['middleware' => ['checkRole']], function () {
Route::get('/single-courses/{slug}', 'PagesController#detail_courses')->name('detail_courses');
Route::post('/single-courses/{slug}/{id}', 'PagesController#memberPost')->name('memberPost');
});
When I was trying the code above, instead an error like this occurred Missing required parameters for [Route: memberPost] [URI: single-courses / {slug} / {id}].

Your route named memberPost has another parameter($slug) that needs to be passed
Route::post('/single-courses/{slug}/{id}', 'PagesController#memberPost')->name('memberPost');
In your form action's route, you need to pass the slug as well
{{route('memberPost', ['slug' => $courses->slug, 'id' => $courses->id])}}

Related

How to redirect to my new post when I created a new post | Laravel

I want to redirect to my new post when I created a new post in Laravel
But I get a ArgumentCountError
Too few arguments to function App\Http\Controllers\ArticlesController::store(), 1 passed in C:\xampp\htdocs\forum\vendor\laravel\framework\src\Illuminate\Routing\Controller.php on line 54 and exactly 2 expected
How can I fix it? Thanks
web.php
<?php
Route::resource('articles', ArticlesController::class);
Route::get('/', [ArticlesController::class, 'index'])->name('root');
Route::resource('articles.comments', CommentsController::class);
ArticlesController.php
public function store(Request $request, $id) {
$content = $request->validate([
'title' => 'required|max:30',
'content' => 'required|min:10'
]);
//限制只有透過登入才能CREATE文章
auth()->user()->articles()->create($content);
return redirect('articles/'. $id)->with('notice', '文章發表成功!');
}
create.blade.php
<form class="container-fluid" action="{{ route('articles.store') }}" method="post">
Check your store() method. I think it should get only Request $request.
Example
public function store(Request $request) {
$content = $request->validate([
'title' => 'required|max:30',
'content' => 'required|min:10'
]);
//限制只有透過登入才能CREATE文章
$article = Article::create($content); // static is not best practice, only for example
return redirect('articles/'. $article->id)->with('notice', '文章發表成功!');
}
But before using the create method, you will need to specify either a fillable or guarded. Check docs
Presumably you need / have a way of viewing an article anyway, whether it's just been added or not, so in your web.php you would want a GET request to retrieve an article by passing its ID:
Route::get('/article/{id}', [ArticleController::class, 'viewArticle'])-> name('article.view');
Then you would want a POST request to add a new article :
Route::post('/addarticle', [ArticleController::class, 'addArticle'])-> name('article.add');
In your ArticleController, at the end of your addArticle method, once your new article has been created, you can then return a redirect to your "view article" route referencing its name, and passing in the parameter that it expects - the new article's ID - as part of the route, like so :
$article = new Article();
... populate the article's details here ...
return redirect()->route('article.view', ['id' => $article->id]);
I already solved it by my way
remove $id from store() function
just add $article before auth()->user()->articles()->create($content)
$id change to $article->id from redirect()
Example
public function store(Request $request) {
$content = $request->validate([
'title' => 'required|max:30',
'content' => 'required|min:10'
]);
$article = auth()->user()->articles()->create($content);
return redirect('articles/'. $article->id)->with('notice', '文章發表成功!');
}
Thank you

How to call controller update method from blade laravel?

form method="put" action="{{URL::action('siteController#update')}}" accept-charset="UTF-8"></form>
Route::post('site/update/{id}', 'siteController#update');
public function update(Request $request, $id)
{
//
$this->validate($request,[
'Name' => 'required',
'Description' => 'required',
'Status' => 'required'
]);
$Data = site::find($id);
$Data->Name = $request->Name;
$Data->Description = $request->Description;
$Data->Status = $request->Status;
if($Data->save())
{
return $this->index();
}else{
return redirect()->back()->withErrors($errors,$this->errorBag());
}
}
By adding a name to your route such as
Route::post('site/update/{id}', 'siteController#update')->name('site-update');
It allows you to generate its URL without knowing it at all
<form method="post" action="{{ route('site-update', compact('id')) }}">
#csrf
add your form field here and use button type submit
</form>
Even if you decide to change the URL, the route helper does not care as long as the name stays the same (it's just an alias)
Try This,
<form method="post" action="{{ url('site/update/', ['id' => $id]) }}">
#csrf
add your form field here and use button type submit
</form>

Laravel 5: Trying to get property of non-object through method injection

I am using Route-Model-Binding with method injection to retrieve the $post->id of the post I am commenting on, but I keep getting this error
Trying to get property of non-object (View: C:\xampp\htdocs\reddit\resources\views\partials\post.blade.php) (View: C:\xampp\htdocs\reddit\resources\views\partials\post.blade.php)
This is the method I have, injecting Post $post then trying to get $post->id
dd($post) retrieves nothing at all even if I dump the model alone.
public function post_this_comment(Request $request, Post $post) {
$post = Post::whereId($post->id)->first(); // this is where I'm getting the post
$comment = new Comment;
$comment->user_id = Auth::id();
$comment->comment = $request->input('commenter_comment');
$comment->parent_id = $request->input('commenter_parent');
if($comment->parent_id > 0){
$my_parent = Comment::find($comment->parent_id);
$comment->parents = $my_parent->parents.'.'.$comment->parent_id;
}else{
$comment->parents = '0';
}
$comment->save();
$per_page = $request->input('per_page');
$comment_list = view('post/show')
->with('comments', $this->comment_list($per_page, $request))
->with('total_comments', $this->total_comments())
->with('per_page', $per_page)
->with('post', $post)
->render();
$response = array(
'status' => 'success',
'msg' => 'Comment Saved!',
'comment_list' => $comment_list
);
return Response::json($response);
}
This is the view, I have opened a form even though I don't need it because I'm submitting data via ajax.
{!! Form::open(['route' => ['post_this_comment', $post]]) !!}
<div class="comment-fields">
<div class="commenter-comment">
<div class="form-group col-md-12">
<textarea id="commenter_comment" name="commenter_comment" class="form-control comment-field" title="User's comment" placeholder="Comment Text"></textarea>
</div>
</div>
<div class="commenter-name-email">
<input type="hidden" id="commenter_parent" name="commenter_parent" class="commenter-parent" value="0">
</div>
<div class="commenter-captcha">
<div class="col-md-3 text-right">
Comment
</div>
</div>
{!! Form::close() !!}
Routes
Route::resource('posts', 'PostsController');
Route::post('{post}/post_this_comment', ['as' => 'post_this_comment', 'uses' => 'PostsController#post_this_comment']);
RouteServiceProvider
$router->model('articles', 'App\Article');
$router->model('subreddit', 'App\Subreddit');
$router->model('posts', 'App\Post');
$router->model('moderators', 'App\Moderator');
$router->model('comments', 'App\Comment');
The parameter in your route needs to match the one you used for your route model binding. In your case you have defined posts: $router->model('posts', 'App\Post'); but you are using {post} (without the 's') as the parameter in your route. Instead your route should be:
Route::post('{posts}/post_this_comment', ['as' => 'post_this_comment', 'uses' => 'PostsController#post_this_comment']);
If you want to inject your Post model in to you method.
You should bind the model using something like this:
$router->model('post', 'App\Post'); // 'post' parameter is used here
So that you can use the following:
Route::post(
'{post}/post_this_comment', // post parameter is used here
[
'as' => 'post_this_comment',
'uses' => 'PostsController#post_this_comment'
]
);
Bith parameters should match. When you bind some model using a parameter for example, $router->model('user', 'App\User') you said the framework to bind the appropriate User model when it sees a user parameter used in a route.

Generating URL::route with parameter in Laravel 4

I am having trouble getting getting my parameter of 'item id' to tack onto the end of my route being generated for my form action url.
I have a page setup to 'update' an existing item. The routes looks something like this:
Route::get('/item/edit/{id}', array(
'as' => 'item-edit',
'uses' => 'ItemController#getEditItem',
));
Route::post('/item/edit/{id}', array(
'as' => 'item-edit-post',
'uses' => 'ItemController#postEditItem',
));
and my ItemController contains these methods:
public function getEditItem($id) {
$states = State::where('user_id', '=', Auth::user()->id)->get();
$types = Type::where('user_id', '=', Auth::user()->id)->get();
$item = Item::where('user_id', '=', Auth::user()->id)
->where('id', '=', $id)
->first();
return View::make('items.edit')
->with('item', $item)
->with('states', $states)
->with('types', $types);
}
public function postEditItem($id) {
// Validate input for Item changes
$validator = Validator::make(Input::all(),
array(
'label' => 'required|min:3|max:128|unique:items,label,null,id,user_id,' . Auth::user()->id,
'type_id' => 'required|integer',
'state_id' => 'required|integer',
)
);
if( $validator->fails() ) {
return Redirect::route('item-edit')
->withErrors($validator)
->withInput();
} else {
$item = Item::find($id);
$item->label = Input::get('label');
$item->type_id = Input::get('type_id');
$item->state_id = Input::get('state_id');
$item->save();
return Redirect::route('item-create')
->with('global', 'Your new item has been edited successfully!');
}
}
The last piece of the puzzle is my items.edit view:
#extends('layout.main')
#section('content')
<form action="{{ URL::route('item-edit-post', $item->id) }}" method="post" class="form-horizontal form-bordered" autocomplete="off">
<!-- some inputs and such -->
</form>
#stop
The action URL being generated here is wrong:
<form method="POST" action="http://manageitems.com/item/edit/%7Bid%7D" accept-charset="UTF-8" hello="hello" class="form-horizontal form-bordered">
For some reason it is escaping my {id} in the route and not adding on the actual item ID on the end of the route. I have tried a few different ways of doing this and read through the route parameter docs, but I haven't made any progress. I also tried using Laravel's for builder like so:
{{ Form::open(array('action' => 'ItemController#postEditItem', $item->id, 'class'=>'form-horizontal form-bordered')) }}
but this did the same thing. I am new to Laravel so this may be a simple problem that I am overlooking, any help is much appreciated.
Use an array in the second parameter.
URL::route('item-edit-post', ['id' => $item->id])
Or the route helper (what I would go with, fits more in view files).
route('item-edit-post', ['id' => $item->id])
It seems that $item->id returns null.
And this is how you do it, when you specify action or route in the Form::open:
Form::open(['route' => ['some.route', $param]]);
Form::open(['action' => ['controller#action', $param]]);

laravel test fail in route redirection

i am testing a form. Upon success it must redirect to a route.
Here is the route excerpt
<?php
Route::group(array('prefix'=>'categories'), function(){
Route::get('/', array('as'=>'categories', 'uses'=>'CategoryController#getCategory'));
Route::get('addcategory',array('as'=>'getcategoryform', 'uses'=>'CategoryController#getCategoryForm'));
Route::post('addcategory', array('as'=>'postcategoryform', 'uses' => 'CategoryController#postCategoryForm'));
});
This is the controller
class CategoryController extends BaseController {
// adding Category model instance in the controller through the constructor
public function __construct(Category $category){
$this->category = $category;
}
public function getCategoryForm(){
return View::make('dashboard.addcategoryform');
}
public function postCategoryForm(){
$rules = ['category_name' => 'required|between:3,20', 'options' =>'required'];
$validator = Validator::make(Input::all(), $rules);
if($validator->passes()){
$category = new Category;
$category->category_name = Input::get('category_name');
$category->options = Input::get('options');
$category->save();
Session::flash('message', 'Category Added Successfully');
return Redirect::route('categories');
}else return Redirect::route('getcategoryform')->withErrors($validator);
}
here's the view
#extends('layouts.main')
#section('content')
<div class="g12">
<h1>Add Category</h1>
{{Form::open(array('route'=>'postcategoryform'))}}
{{ Form::text('category_name', Input::old('category_name'), array('placeholder' => 'eg article') )}}
<textarea id="textarea_auto" name="options" value="Input::old('options')" placeholder="eg. author, facts, tags, reference, book"></textarea>
{{Form::submit('Add')}}
{{Form::close()}}
</div>
#stop
This is the test that i tried:
public function testPassedPostCategoryForm(){
Input::replace(['category_name' => 'dummycat', 'options' => 'dummyoption']);
$this->mock
->shouldReceive('create')
->once();
$this->app->instance('Category', $this->mock);
$this->call('POST', 'categories/addcategory');
$this->assertRedirectedToRoute('categories');
}
The test is failing. This is the error i'm, receiving:
There was 1 failure:
1) CategoryControllerTest::testPassedPostCategoryForm
Failed asserting that two strings are equal.
--- Expected
+++ Actual
## ##
-'http://localhost/categories'
+'http://localhost/categories/addcategory'
In your code, the validator is not passed.
So the redirect back to http://localhost/categories leads to fail result.
It goes well if you delete the validator, and simply return such that
public function postCategoryForm(){
$rules = ['category_name' => 'required|between:3,20', 'options' =>'required'];
$validator = Validator::make(Input::all(), $rules);
return Redirect::route('categories');
}
Or you can rewrite the test code as follows,
$this->call('POST', 'categories/addcategory', array( 'category_name'=> 'dummycat' ,
'options' => 'dummyoption'));
or
$this->route('POST','getcategoryform',array( 'category_name'=> 'dummycat' ,
'options' => 'dummyoption'));
instead of
$this->call('POST', 'categories/addcategory');
[Edit] Further, delete followings
$this->mock
->shouldReceive('create')
->once();
,because the 'create' method is not called in the controller.

Categories