Laravel Resource API CURL | store/delete don't work [duplicate] - laravel

This question already has an answer here:
Laravel HttpException - No error message
(1 answer)
Closed 4 years ago.
I'm trying to create my own resource API in Laravel, I test the api via Postman program, index() and show() functions (with GET requests) work well, but unfortunatelly store()/delete() functions dont't work (POST, PUT, DELETE requests).
I've tried a lot of tutorials, and result the same, I can't use POST, PUT, DELETE requests (or can't test them properly via Postman)
More details:
I have DB with tables (with relations): Categories, Startups, Contacts, Countries
1.1 One Category can have many Startups
1.2 One Contact can have many Startups
1.3 One Country can have many Contacts
I defined Api Routes in web.php (not in api.php), (I'm trying to make api for Startups Table):
// get list startups
Route::get('api/startups', 'Admin\StartupController#index');
// get single startup
Route::get('api/startup/{id}', 'Admin\StartupController#show');
// create new startup
Route::post('api/startup', 'Admin\StartupController#store');
// update startup
Route::put('api/startup', 'Admin\StartupController#store');
// delete startup
Route::delete('api/startup/{id}', 'Admin\StartupController#destroy');
Controller code (StartupController), I'm showing only one method - store()
(I think it's enough for identifying the issue)
public function store(Request $request) {
$startup = Startup::create([
'category_id' => $request->category()->id,
'contact_id' => $request->contact()->id,
'name' => $request->name,
'description' => $request->description,
'url' => $request->url,
'logo' => $request->logo,
]);
return new StartupResource($startup);
Also second option of the function (which doesn't work too):
public function store(Request $request) {
$startup = $request->isMethod('put') ? Startup::findOrFail($request->startup_id) : new Startup;
$startup->id = $request->input('startup_id');
$startup->name = $request->input('startup_name');
$startup->description = $request->input('startup_description');
$startup->url = $request->input('startup_url');
$startup->logo = $request->input('startup_logo');
if ($startup->save()) {
return new StartupResource($startup);
}
}
My migration
Schema::create('startups', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id');
$table->integer('contact_id')->nullable();
$table->string('name');
$table->mediumText('description');
$table->string('url');
$table->boolean('public')->default(false);
$table->string('logo');
$table->timestamps();
});
toArray() function in resources
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'url' => $this->url,
'public' => $this->public,
'logo' => $this->logo,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
'category' => $this->category,
'contact' => $this->contact
];
}
(Additional) may be it will help - how I test it in Postman
row (submitting json)
form-data

I think it's a CSRF protection.
https://laravel.com/docs/5.7/csrf
api.php routes don't have this protection(only web.php).
So, you should decide - use api routes, or just use VerifyCsrfToken::$except property to avoid this protection for some routes.

Related

How to upload file in relationship hasOn<->belongsTo Laravel Backpack

Can be possible to store a file uploaded to a related table?
Scenario: I have a usres table in database and another one pictures. Users Model have the following function
public function picture()
{
return $this->hasOne(Picture::class);
}
And the Picture Model have the following function.
public function user_picture()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
Is possible to store the picture in pictures database table (id, user_id, img_path) from the UserCrudController store() function?
try something like this
public function store(Request $request)
{
Picture::create([
'user_id' => // get the user id from $request or auth()->user(),
'img_path' => $request->file('image')->store('images', 'public'),
]);
return // your view or something else
}
Let's say it is a registration form that need to insert an image. Instead of using the Picture model directly you can just do this :
public function store(Request $request)
{
$request->validate(...);
$user = User::create(...);
//It will ensure that the image belongs to the user.
$user->picture()->create([
'image_path' => $request->file('image')->store('images');
])
}
I resolved the issue with the following steps.
As per Laravel Backpack I added the input field in the Blade:
#include('crud::fields.upload', ['crud' => $crud, 'field' => ['name' => 'img1', 'label' => 'Image 1', 'type' => 'upload', 'upload'=> true, 'disk'=>'uploads', 'attributes' => ['id' => 'img1', 'capture' => 'user']]])
After this I added the function in the User Controller as follow:
$request->validate(['img1' => 'mimes:jpg,png,jpeg|max:5120']);
$fileModel = new Picture;
if($request->file()) {
$fileName1 = time().'_'.$request->img1->getClientOriginalName();
$filePath1 = $request->file('img1')->storeAs('uploads', $fileName1, 'public');
$fileModel->name = time().'_'.$request->img1->getClientOriginalName();
$fileModel->img1 = '/storage/' . $filePath1;
$fileModel->save();
}
With these lines of code I was able to store the related Picture with the User.
Thank you all for the guidelines.

Validating form comaring two fields values

I'm trying to find Laravel 8 documentation on how to validate comparing two fields to each other. I'm creating an app that allows creating matches from teams in a database table, using the create() method in the controller. I looked into Laravel #Validation, even #Custom Validation Rules, but I can't find anything when comparing the two fields.
public function store(Request $request)
{
$validatedData = $request->validate([
'local_team' => 'required',
'local_score' => 'required|numeric',
'visitor_team' => 'required',
'visitor_score' => 'required|numeric',
]);
$score = new Score();
$score->local_team = $request->local_team;
$score->local_score = $request->local_score;
$score->visitor_team = $request->visitor_team;
$score->visitor_score = $request->visitor_score;
$score->save();
$new = true;
return redirect()->route('scores.show',
['id' => $score->id, 'new' => true]);
}
In my case, the 'local_team' and 'visitor_team' fields should be different. Any clue on how to do it?

Property [user] does not exist on this collection instance

i'm developping a social app using React in the frontend and laravel in the backend.
I'm trying to receive all posts with their likes,users,comments. I have these relation ships:
1/ User model has many posts and Post model belongs to a user.
2/ Post model has many likes
3/ Post model has many comments and one comment belongs to a user.
When getting all posts back, im succefully getting its likes and users information, but for comments i wanna get the user's comment. So i did $posts->comments->user->user_name
And then, i got the error: Property [user] does not exist on this collection instance. But when i tried to get comments infos, it worked normally($posts->comments)
My comment relation in Post model:
public function comments()
{
return $this->hasMany('App\Models\Comment');
}
My user relation in Comment Model:
public function user()
{
return $this->belongsTo('App\Models\User');
}
My method in PostController when i'm trying to get all posts:
public function allPosts()
{
$posts = Post::with('user','likes','comments')->get();
if($posts->count() < 1) {
return response()->json([
'success' => false,
'message' => 'There are no posts!'
]);
}else {
return response()->json([
'success' => true,
'data' => PostResource::collection($posts),
'message' => 'Succefully retreived all posts!'
]);
}
}
As you noticed i'm sending the Data through a Resource, so My PostResource's method :
public function toArray($request)
{
// return parent::toArray($request);
return [
'id' => $this->id,
'user_id' => $this->user_id,
'content' => $this->content,
'image_path' => $this->image_path,
'user' => $this->user,
'likes' => $this->likes->count(),
'isLiked' => $this->likes->where('user_id', auth()->user()->id)->isEmpty() ? false : true,
'comment_user' => $this->comments->user->user_name,
'created_at' => $this->created_at->format('d/m/y'),
'updated_at' => $this->updated_at->format('d/m/y')
];
}
As i said, everything is okey, just for comment_user it says:Property [user] does not exist on this collection instance, and when i tried to get only comments info it worked:
'comments' => $this->comments,
Any help please? and thnx in advance.
Maybe you need to add relation user() to Post model?

Two store() methods, one doesn't work (Call to undefined method save())

One of two similar store methods doesn't work. Could you clarify this for me?
Relations
A Team hasMany Users <> A User belongsTo a Team
A User hasMany Characters <> A Character belongsTo a User
Working Code (CharacterController)
public function store()
{
$fighters = Fighter::pluck('name')->toArray();
$this->validate(request(), [
'name' => 'required|min:3|max:25|alpha_num|not_in:'.Rule::notIn($fighters).'unique:characters',
'fighter' => 'required|in:'.Rule::in($fighters),
]);
auth()->user()->characters()->save(new Character([
'name' => request('name'),
'fighter' => request('fighter'),
]));
return redirect()->route('character.index');
}
Not Working (TeamController)
public function store()
{
$this->validate(request(), [
'name' => 'required|min:3|max:25|alpha_num|unique:teams',
]);
auth()->user()->team()->save(new Team([
'name' => request('name'),
'fame' => 0,
]));
return redirect()->route('team.index');
}
Questions
Why is the same method not available? Is it relation stuff?
Is the create method better? Should I try to use it?
Thought I know what I'm doing, now it turns out I don't...
Thank you for helping.
team() is a belongsTo relation, you probably have a team_id col in your user table which you want to associate with the team.
public function store()
{
$this->validate(request(), [
'name' => 'required|min:3|max:25|alpha_num|unique:teams',
]);
// create and save team
$team = new Team([
'name' => request('name'),
'fame' => 0,
]);
$team->save();
// associate current authenticated user with team (set foreign key) and save user
auth()->user()->team()->associate($team)->save();
return redirect()->route('team.index');
}

Passing Object between Models

I have a a couple of Models like so (some code removed for simplicity)
class Poll extends Model
{
public function poll()
{
return $this->hasOne('App\PollQuestion', 'pollId');
}
}
class PollQuestion extends Model
{
public function poll()
{
return $this->belongsTo('App\Poll');
}
}
I then have all my routes set up, for the PollQuestion they currently look like this
Route::model('polls.questions', 'PollQuestion');
Route::get('/admin/polls/{id}/addquestions', [
'as' => 'polls.questions.create',
'uses' => 'PollQuestionController#addQuestions'
]);
Route::post('/admin/polls/{id}/storequestions', [
'as' => 'polls.questions.store',
'uses' => 'PollQuestionController#storeQuestion'
]);
In my PollQuestionController, to see the questions view I have
public function addQuestions(Request $request)
{
$poll = Poll::where('id', '=', $request->id)->first();
return view('poll.admin.questions', compact('poll'));
}
Inside this view if I dump the poll e.g.
{{ dd($poll) }}
I can see what I expect to see. For the question form, I am doing
{!! Form::model(new App\PollQuestion, [
'route' => ['polls.questions.store', $poll]
]) !!}
So I presume that should pass my store function the Poll Object I previously dumped. However, in the store function, I do
public function storeQuestion(Request $request, Poll $poll) {
dd($poll);
}
And it shows Null. Why would this happen seeing that I am passing it the Poll Object I had previously dumped?
Thanks
You need use Route Model Binding correctly. According to Laravel Documentation
Route::model('poll-question', App\PollQuestion::class);
Route::get('/admin/polls/{poll-question}/addquestions', [
'as' => 'polls.questions.create',
'uses' => 'PollQuestionController#addQuestions'
]);
Route::post('/admin/polls/{poll-question}/storequestions', [
'as' => 'polls.questions.store',
'uses' => 'PollQuestionController#storeQuestion'
]);
Route::model define a variable in the route like a Model. This method searches the primary key passed in the route and retrieve the Model.

Resources