Manually Passing a Foreign key Value - laravel

I can not pass a foreign key value (which is user_id) to my newly created article.
Here is my code...
<?php
if (is_null($request->user_id)) {
$request->user_id = $user->user_id;
}
$request->validate(['title' => 'Required|string|min:3', 'body' => 'Required|string|min:5', 'user_id' => 'Required|exists:users,user_id']);
if ($article = Article::create($request->all())) {
event(new ArticleCreated($user));
return response()->json(['success' => true, 'reason' => 'Article Created successfully', $article]);
} else {
return 'Article could not be created';
}

Change this:
if($article = Article::create($request->all())) {
$article->user_id = $request->user_id;
$article->save();
event(new ArticleCreated($user));
return response()->json(['success' => true, 'reason' => 'Article Created successfully', $article]);
}

Try this,
public function store(Request $request)
{
$request->validate([
'title' => 'Required|string|min:3',
'body' => 'Required|string|min:5',
]);
$data = $request->all();
//you don't need to validate user_id is correct
//if you are using auth middleware in the route
$user = auth()->user()
$data['user_id] = $user->id
if ($article = Article::create($data)) {
event(new ArticleCreated($user));
return response()->json([
'success' => true,
'reason' => 'Article Created successfully',
$article
]);
} else {
return 'Article could not be created';
}
}
Hope this helps

Check your fillable array in Article model, there must be user_id, and check if the user id is passed in the $request->all().

Related

Laravel Many to one in Resource

I use laravel 8 & have 3 table:
Products, ProductPrice & ProductsPublisher:
this is my Products model for this relationship:
public function lastPrice(){
return $this->hasMany(ProductPrice::class)->where('status','active')->orderBy('created_at','DESC')->distinct('publisher_id');
}
and this is my productsPrice model for publisher relationship:
public function getPublisher(){
return $this->belongsTo(ProductsPublisher::class,'publisher_id');
}
now, i want to use laravel resource for my api, i wrote products resource:
public function toArray($request)
{
return [
'id' => $this->id,
'price' => lastPrice::make($this->lastPrice),
'status' => $this->status,
'slug' => $this->slug,
'title' => $this->title,
'description' => $this->description,
'txt' => $this->txt,
'lang' => $this->lang,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
but in lastPrice resource, when i wrote like this:
return [
'id' => $this->id,
'main_price' => $this->main_price
];
it give me this error:
Property [id] does not exist on this collection instance.
when i use this code:
return parent::toArray($request);
get response but because i need to use another relationship in my lastPirce for publishers, i cant use that code and should return separately my data.
What i should to do?
thanks
Edit 1:
this is my Controller Code:
$products = Product::where('id',$id)->where('slug',$slug)->where('status','confirm')->first();
if(!$products){
return $this->sendError('Post does not exist.');
}else{
return $this->sendResponse(new \App\Http\Resources\Products\Products($products), 'Posts fetched.');
}
and this is sendResponse & sendError:
public function sendResponse($result, $message)
{
$response = [
'success' => true,
'data' => $result,
'message' => $message,
];
return response()->json($response, 200);
}
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'success' => false,
'message' => $error,
];
if(!empty($errorMessages)){
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
thanks.
Edit 2:
i change my lastPrice Resource toArray function to this and my problem solved, but i think this isn't a clean way, any better idea?
$old_data = parent::toArray($request);
$co = 0;
$new_data = [];
foreach ($old_data as $index){
$publisher_data = Cache::remember('publisher'.$index['publisher_id'], env('CACHE_TIME_LONG') , function () use ($index) {
return ProductsPublisher::where('id' , $index['publisher_id'])->first();
});
$new_data[$co]['main_prices'] = $index['main_price'];
$new_data[$co]['off_prices'] = $index['off_price'];
$new_data[$co]['publisher'] = SinglePublisher::make($publisher_data);
$new_data[$co]['created_at'] = $index['created_at'];
$co++;
}
return $new_data;

GET /account: Returns API Token on response

When the user created a new account I added it's API token and returned it to the user. But I'm having trouble wanting to return the API token to the user when they view their account information.
GET /account: Returns API Token in response.
This is my code file User.php:
public function index()
{
$users = User::where('id', auth()->user()->id)->get();
return response([
'data' => UserResource::collection($users),
'message' => 'Retrieve successfully'
], 200);
}
// POST
public function store(Request $request)
{
$data = $request->all();
$validator = Validator::make($data, [
'name' => 'required|max:255|string',
'email' => 'required|email|unique:users,email',
'password' => 'required|string',
]);
if ($validator->fails()) {
return response(['error' => $validator->errors(), 'Validation Error'], 400);
}
$users = User::create($data);
$token = $users->createToken('accessToken')->plainTextToken;
return response([
'data' => new UserResource($users),
'api_token' => $token,
'message' => 'Created successfully'
], 201);
}
This is my code file api.php (route):
Route::group(['prefix' => 'v1' ], function () {
// Account
Route::post('/account', [UserController::class, 'store']);
// Protected route
Route::group(['middleware' => ['auth:sanctum']], function () {
// Account
Route::get('/account', [UserController::class, 'index']);
});
});
Use $request->bearerToken() to get bearer token.
public function index()
{
$users = User::where('id', auth()->user()->id)->get();
return response([
'data' => UserResource::collection($users),
'api_token' => $request->bearerToken(),
'message' => 'Retrieve successfully'
], 200);
}

Error column not found, but I did not declare the column?

I'm inserting a record to a polymorphic imageable table, however it says column thread_id not found. I have not declared this thread_id column and I don't know where it's pulling it from. Here is the code it's trying to run.
protected static function bootRecordImage()
{
if (auth()->guest()) return;
foreach (static::getMethodToRecord() as $event) {
static::$event(function ($model) use ($event) {
$body = request()->body;
preg_match_all('/<img .*?(?=src)src=\"([^\"]+)\"/si', $body, $matches);
$images = $matches[1];
if($event == 'created') {
foreach ($images as $image) {
$model->images()->create([
'user_id' => auth()->id(),
'imageable_id' => $model->id,
'imageable_type' => get_class($model),
'path' => $image
]);
}
}
if($event == 'deleting') {
foreach ($images as $image) {
$model->images()->delete([
'user_id' => auth()->id(),
'imageable_id' => $model->id,
'imageable_type' => get_class($model),
'path' => $image
]);
if (File::exists(public_path($image))) {
File::delete(public_path($image));
}
}
}
});
}
}
My store method:
public function store(Request $request, Channel $channel, Spam $spam)
{
if (!auth()->user()) {
return back()->withInput()->with('flash', 'Sorry! You must be logged in to perform this action.');
}
if (!auth()->user()->confirmed) {
return back()->withInput()->with('flash', 'Sorry! You must first confirm your email address.');
}
$this->validate($request, [
'title' => 'required',
'body' => 'required',
'channel_id' => 'required|exists:channels,id',
'g-recaptcha-response' => 'required'
// yes it's required, but it also needs to exist on the channels model, specifically on the id
]);
$response = Zttp::asFormParams()->post('https://www.google.com/recaptcha/api/siteverify', [
'secret' => config('services.recaptcha.secret'),
'response' => $request->input('g-recaptcha-response'),
'remoteip' => $_SERVER['REMOTE_ADDR']
]);
// dd($response->json());
if (! $response->json()['success']) {
throw new \Exception('Recaptcha failed');
}
$spam->detect(request('title'));
$spam->detect(request('body'));
$thread = Thread::create([
'user_id' => auth()->id(),
'channel_id' => request('channel_id'),
'title' => request('title'),
'body' => request('body'),
//'slug' => str_slug(request('title'))
]);
return redirect('/forums/' . $thread->channel->slug . '/' . $thread->slug);
}
As you can see, no where is a thread_id mentioned, yet in the error it looks like it's trying to insert into a thread_id column that I've never declared.
Thanks for reading.
I put the polymorphic relation in the model and the trait. Remove it from the Model and you're good to go.

Laravel index and store views are in the same page approach

I have a page which views posts as well as add posts.
In my controller, I have two methods which return to the same page:
public function index () {
return view('posts.index', [
'posts' => Post::all()
]);
}
and
public function store (Request $request) {
$validator = validate($request);
if ($validator->fails()) {
return view('posts.index', [
'message' => $validator->messages(),
'status' => '400'
]);
}
$post = new Post;
$post->title = $request->title;
$post->body = $request->body;
$post->user_id = 1;
$post->save();
return view('posts.index', [
'message' => 'Successfully published post!',
'status' => '200'
]);
}
Now when storing new post, the index view loses the posts data from the index method. Does it mean that in my every update, I should include posts variable?
public function store (Request $request) {
$validator = validate($request);
if ($validator->fails()) {
return view('posts.index', [
'message' => $validator->messages(),
'status' => '400',
'posts' => Post::all()
]);
}
$post = new Post;
$post->title = $request->title;
$post->body = $request->body;
$post->user_id = 1;
$post->save();
return view('posts.index', [
'message' => 'Successfully published post!',
'status' => '200',
'posts' => Post::all()
]);
}
I am new to Laravel by the way.
Usually, the store() (and update() and delete()) methods of a Controller don't need a view. Instead of showing a view, redirect to a different route when storing/updating/deleting was successful.
Replace
return view('posts.index', [
'message' => 'Successfully published post!',
'status' => '200'
]);
with
return redirect()
->route(NAMEOFYOURINDEXROUTE)
->with('message', 'Successfully published post!');
where NAMEOFYOURINDEXROUTE is the name of the route you want to redirect to. (This could be a dashboard or the list/index of products etc. - you decide)
More on redirecting: https://laravel.com/docs/master/redirects
and redirecting with flash messages: https://laravel.com/docs/master/redirects#redirecting-with-flashed-session-data
Edit:
As #user3532758 pointed out, here's a link worth mentioning: https://en.wikipedia.org/wiki/Post/Redirect/Get (Basically, redirecting to a different route prevents accidental re-submission of the data when refreshing the page in the browser)

laravel 5.2 - check if field is empty or not

I want to check if some field is empty or not. If is empty, the user can update the profile without change the current password.
If is not empty, store new value of password. My controller is:
public function storeUpdatedUser(Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'surname' => 'required', ]);
$user = User::findOrFail(Auth::user()->id);
$user->update($request->all());
$new_password = false;
if($new_password != ""){
$new_password = bcrypt($request->new_password);
$user->password = $new_password;
}
$user->save();
Session::flash('flash_message', 'User updated!');
return redirect('/');
}
but dont work, no password change if I put some value
image explain better
Try this:
public function storeUpdatedUser(Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'surname' => 'required', ]);
$user = User::findOrFail(Auth::user()->id);
$user->update($request->all());
if(!empty($request->input('new_password'))) {
$new_password = bcrypt($request->input('new_password'));
$user->password = $new_password;
$user->save();
}
Session::flash('flash_message', 'User updated!');
return redirect('/');
}
Laravel Check Request Input Exists
if($request->has('new_password ')) {
dd('new_password is exists.');
} else {
dd('new_password is not exists.');
}
Laravel Check Request Input Field Empty or not
if($request->filled('new_password ')) {
dd('new_password is not empty.');
} else {
dd('new_password is empty.');
}
Laravel Check Request Input Field Empty or not
if(!empty($request->input('new_password '))) {
dd('new_password is not empty.');
} else {
dd('new_password is empty.');
}
This is what works for me in Laravel 5.7:
$user = Auth::user();
$user->update($request->filled('password') ? $request->all() : $request->except(['password']));

Resources