Laravel 6 - validate unique, ignore on two conditions - same user and name. Also $this->id is null on update - laravel

I have the following rule so far.
$rules['name'] = [
'required',
'string',
'min:3',
'max:255',
Rule::unique('user_templates', 'name')->ignore($this->id),
];
Users can create records, but all his records must have a unique name (other users can have records with the same name). How can I do this? Also, $this->id on update is always null. What am I doing wrong?
Controller
public function update(UserTemplatesRequest $request, $slug)
{
try {
$model = UserTemplates::where('slug', XSS::clean($slug))
->firstOrFail();
} catch (ModelNotFoundException $err) {
return redirect()->action('UserTemplatesController#index');
}
$data = $request->validated();
if ($model->updateTemplate(XSS::clean($data, ['file']), $request)) {
$message = "There was an error, please try again";
$action = 'index';
$id = '';
} else {
$message = "Category Updated";
$action = 'edit';
$id = $model->id;
}
return redirect()->action("CategoriesController#{$action}", [$id])
->with('message', $message);
}

According to your Rule you can try and use a where clause to narrow it down to one user and not whole project like:
Rule::unique('user_templates', 'name')->where(function (Builder $query) {
return $query->where(
'user_id', '=', $this->user()->id;
})
user_id is the column inside your user_templates table that works as a foreign key with your users table.
About $this->id it should be $this->user()->id to retrieve your user id

Related

I am having issue while keeping the same slug if we don't change title while updating

I am having issue while keeping the same slug if we don't change title while updating, slug take the value of title. I have made a function to create slug. But when i update the same function automatically changes slug because it already exists in DB.
public function createSlug($title, $id = 0)
{
$slug = str_slug($title);
$allSlugs = $this->getRelatedSlugs($slug, $id);
if (! $allSlugs->contains('slug', $slug)){
return $slug;
}
$i = 1;
$is_contain = true;
do {
$newSlug = $slug . '-' . $i;
if (!$allSlugs->contains('slug', $newSlug)) {
$is_contain = false;
return $newSlug;
}
$i++;
} while ($is_contain);
}
// slug function
protected function getRelatedSlugs($slug, $id = 0)
{
return Post::select('slug')
->where('slug', 'like', $slug.'%')
->where('id', '<>', $id)
->get();
}
First of all, you don't need to create a function for that. Just validation will be enough.
use Illuminate\Support\Str;
$validator = $request->validate([
'slug' => ['required''unique:post'],
]);
if ($validator->fails()) {
$generate_extension = Str::random(3);;
}
$newSlug = str_slug($request->title).'-'.$generate_extension;
Then assign the slug.
$post->slug = $newSlug;
In order to keep the same slug you can check if title is changed;
if($post->slug != str_slug($request->title)){
$post->slug = str_slug($request->title);
}
or
if($post->title != $request->title){
$post->slug = str_slug($request->title);
}

Single column not being updated in laravel 5

I am tying to update a single column of a table messages and I have the following code:
public function messageSeen(Request $request){
$data = Message::find($request->id);
$success = Message::where('id', $request->id)->update(array('is_seen' => 1));
if($success){
return response()->json(['status'=>'success'], 200);
} else {
return response()->json(['status'=>'Data not updated'], 404);
}
}
I am getting the response Data not updated. If you question, does the column is_seen exists? then yes it does. Even I tried fetching the data having id $request->id, it gives the proper data. I wonder why is the data not being updated? Am I doing right thing to update column or is there an way out to update column in different way?
I tried the other way like the following:
public function messageSeen(Request $request){
$id = $request->id;
$result = Message::find($id);
dd($result->message);
$data = array();
$data['is_seen'] = 1;
$data['message'] = $result->message;
$data['user_id'] = $result->user_id;
$data['conversation_id'] = $result->conversation_id;
$this->messages->fill($data);
$success = $this->messages->save();
if($success){
return response()->json(['status'=>'success'], 200);
} else {
return response()->json(['status'=>'Data not updated'], 404);
}
}
But here I am getting unexpected thing with this method. Here I am being able to do dd($result) and being able to get data like this:
#attributes: array:9 [
"id" => 22
"message" => "How are you?\r\n"
"is_seen" => 0
"deleted_from_sender" => 0
"deleted_from_receiver" => 0
"user_id" => 2
"conversation_id" => 1
"created_at" => "2019-09-29 03:42:39"
"updated_at" => "2019-09-29 03:42:39"
]
however, if I tried to do dd($result->message) then I get null! What am I doing wrong?
I tried the following code:
public function messageSeen(Request $request){
$id = $request->id;
$result = Message::find($id);
$data = array();
$data['is_seen'] = 1;
$data['message'] = $result[0]['message'];
$data['user_id'] = $result[0]['user_id'];
$data['conversation_id'] = $result[0]['conversation_id'];
$this->messages->fill($data);
$success = $this->messages->save();
if($success){
return response()->json(['status'=>'success'], 200);
} else {
return response()->json(['status'=>'Data not updated'], 404);
}
}
and it worked but instead of updating it is adding new column when the message is seen. But first I don't understand why do I have to do $result[0]['key'] in the first place.
You need to specify which fields in your table can be mass assigned, by adding or updating the $fillable property of your model:
protected $fillable = [..., 'is_seen', 'message', ...];
This is required for the create() and update() methods, as those accept "mass" variables in the array you pass in. Whereas with save() you have to manually, explicitly, assign the properties on the model, so there is no risk of accidentally saving something you didn't mean to. And this is exactly the behaviour you are seeing - update() is not working, but save() is.
You should try this
public function messageSeen(Request $request) {
$input = Request::all();
$data = Message::find($input['id']);
if (!empty($data)) {
$update = array();
$update['is_seen'] = 1;
$success = Message::where('id', $input['id'])->update($update);
if ($success) {
return response()->json(['status' => 'success'], 200);
} else {
return response()->json(['status' => 'Something went wrong'], 400);
}
} else {
return response()->json(['status' => 'Data not updated'], 404);
}
}
Value depends on data type of is_seen are string or integer

Not updating database and not throwing error in laravel

I have an issue while updating the user. When I try to update the user after clicking the save button then it redirect me to the same page and not throwing me any error but also its not updating anything in the database. Below is my code. I have no idea what's going on here. Help me :)
Controller
public function update(ReportRequest $request, $id)
{
$report = Report::findOrFail($id);
$input = $request->all();
if ($file = $request->file('photo_id')) {
$name = time() . $file->getClientOriginalName();
$file->move('images', $name);
$photo = Photo::create(['file' => $name]);
$input['photo_id'] = $photo->id;
}
$report->update($input);
return redirect()->back();
}
Route
Route::resource('admin/reports', 'ReportController', ['names'=>[
'index'=>'admin.reports.index',
'create'=>'admin.reports.create',
'edit'=>'admin.reports.edit',
]]);
Models
class Report extends Model
{
protected $fillable = [
'student_id',
'student_name',
'class_id',
'subject',
'teacher_name',
'report_categories_id',
'total_marks',
'obtained_marks',
'percentage',
'position',
'photo_id',
];
public function photo() {
return $this->belongsTo('App\Photo');
}
public function studentsClass() {
return $this->belongsTo('App\StudentsClass', 'class_id');
}
public function student() {
return $this->belongsToMany('App\Student');
}
}
Make sure you have your $fillable properties in your Photo and Report models, otherwise the create() and update() methods won't work as expected.
Check the $fillable fields in the Model as above. If the error persists check your laravel log on storage/logs/laravel.log.
In controller:
public function update(ReportRequest $request, $id){
$report = Report::findOrFail($id);
$input = $request->all();
try{
if ($request->photo_id != '') {
$path = 'images/';
$file = $request->photo_id;
$name = time() . $file->getClientOriginalName();
$file->move($path, $name);
$photo = Photo::create(['file' => $name]);
$report->update(['photo_id' => $photo->id]);
}
return redirect()->back();
}catch(\Exception $e){
return redirect()->back()->with('error_message', $e->getMessage());
}
}

Using with() and find() while limiting columns with find cancels relation data

I have the following code that displays different data depending on if you are the authenticated user looking at your own data or if you are looking at data from another user. The code works but in my opinion is very nasty.
public function showUserDetailed(Request $request, $username)
{
$key = strtolower($username).'-data-detailed';
if(Auth::user()->usenrame === $username) {
$key = $key .'-own';
}
if(Cache::has($key)) {
if($request->wantsJson()) {
return request()->json(Cache::get($key));
} else {
return view('user/detailed', ['user' => Cache::get($key)]);
}
} else {
if(Auth::user()->username === $username) {
$u = User::where('username', $username)->first();
$user = new \stdClass();
$user->username = $u->username;
$user->email = $u->email;
$user->address = $u->address;
$user->city = $u->city;
$user->state = $u->state;
$user->zip = $u->zip;
$user->phone = $u->phone;
$user->follows = $u->follows;
$user->ratings = $u->ratings;
$user->location = $u->location;
} else {
$u = User::where('username', $username)->first(['username', 'city', 'state']);
$user = new \stdClass();
$user->username = $u->username;
$user->city = $u->city;
$user->state = $u->state;
$user->follows = $u->follows;
$user->ratings = $u->ratings;
}
Cache::put($key, $user);
if($request->wantsJson()) {
return response()->json($user);
} else {
return view('user/detailed', ['user' => $user]);
}
}
}
I have tried to use something similar to the following in the model calls.
User::where('username', $username)->with('follows', 'ratings', 'location')->find(['username', 'city', 'state');
However when I specify the columns to get from the user table it negates the relation data so it comes back as empty arrays. Is there a different way I can do this which would be cleaner? I despise having to create a stdClass to be a data container in this situation and feel I may be missing something.
// this works
User::where('username', $username)->with('follows', 'ratings', 'location')->first();
// this also works
User::where('username', $username)->first(['username', 'city', 'state']);
// this does not
User::where('username', $username)->with('follows', 'ratings', 'location')->first(['username', 'city', 'state']);
When you specify columns and want to get the related models as well, you need to include id (or whatever foreign key you're using) in the selected columns.
The relationships execute another query like this:
SELECT 'stuff' FROM 'table' WHERE 'foreign_key' = ($parentsId)
So it needs to know the id of the parent (original model). Same logic applies to all relationships in a bit different forms.

Attach user id to a post (Laravel 5.3)

in my app I want to attach a logged in user id to a post, below is my controller :
public function storejournal(JournalRequest $request) {
$input = $request->all();
//Input PDF
if ($request->hasFile('file')) {
$input['file'] = $this->uploadPDF($request);
}
//Insert data jurnal
$id = $request->id;
$journal = Edition::findOrFail($id)->journal()->create($input);
$journal->user_id = Auth::id();
$journal->user()->attach($request->input('penulis'));
return redirect()->route('edition', ['id' => $id]);
}
I tried the above controller it gave error : SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert intojournal(title,abstract,file,id_edition,journalslug,updated_at,created_at) values (Rancang bangun website Jurnal Online jurusan Teknik Informatika Universitas Palangkaraya, ddd, test3.pdf, 1, rancang-bangun-website-jurnal-online-jurusan-teknik-informatika-universitas-palangkaraya, 2016-11-15 03:43:34, 2016-11-15 03:43:34))
I don't understand what I did wrong, if someone can help that would be great. Thanks.
You're trying to create a Journal without specifying the user_id when it's created.
I'd suggest the following:
public function storejournal(JournalRequest $request) {
$input = $request->all();
//Input PDF
if ($request->hasFile('file')) {
$input['file'] = $this->uploadPDF($request);
}
//Insert data jurnal
$id = $request->id;
$journal = Edition::findOrFail($id)->journal()->create($input + ['user_id' => Auth::id()]);
$journal->user()->attach($request->input('penulis'));
return redirect()->route('edition', ['id' => $id]);
}
Also, don't forget to have user_id set as mass assignable in the Journal class.
The error says you should pass user_id too. You can do this with adding user ID to an $input:
$input = $request->all();
$input['user_id'] = auth()->user()->id;

Resources