Laravel how to update value in mysql only if value is changed - php

I'm new to Laravel. All I'm trying to do is as follow:
I have some fields in my form like TITLE, DESCRIPTION.
TITLE field is unique in database.
This is what I've done to update my values.
$product = Product::find($id);
$product->title = $request->title;
$product->description = $request->description;
$product->save();
But this will give error (that value already exists) as my TITLE field is unique.
All I want to is update my TITLE only if the TITLE value is changed otherwise update the same value but update other fields. Thanks

Something like this?
$product = Product::find($id);
if ($product->title == $request->title) {
$product->description = $request->description;
} else {
$product->title = $request->title;
}
$product->save();

The code you posted does exactly (if indirectly) what you say you want. Your problem is another: you're assigning a title that is used elsewhere, thereby violating uniqueness.
You must verify that the new title is not already used.
$duplicate = Product::where('title', '=', $request->title)->where('id', '!=', $id)->first();
At this point it is unclear what you want to do:
a) Do you want to use the duplicate record instead of the one indicated by $id?
b) Is this an error?
c) Should the $id record be updated, leaving the title alone?
You can do any of these things; what you can't do is "update my TITLE only if the TITLE value is changed", because the changed value is already in use elsewhere.

I have not seen any of your database structure or form code only the small snippet above you have stated.
you could do something like this...
$checkTitle = Product::where('title', '=', $request->input('title')->first();
You can also do...
$record = Product::find($id)
if($request->input('title') === $record->title){
// Record with the $id has the same title as you are posting in the request.
}else{
// Title for $id lets say id number 3, Is not the same as the form request you are sending so now Perform insert
}
if(count($checkTitle) >= 1){
// Means the title exists and do what ever you want...
// Perform update
}else{
// Perform insert
}
Sorry for short and sweet, leaving to go to office and thought it might help to post now. Let me know if im on the wrong tracks and ill help where i can.

You can use if statement to check weather column value is same with original?
$currentProduct = Product::find($id);
//Check and update if title not same
if($currentProduct->title == $request->title){
$currentProduct->description = $request->description;
}
//Update title and description...
else {
$currentProduct->title = $request->title;
$currentProduct->description = $request->description;
}
$currentProduct->save();

You should look at wasChanged() function in Laravel.

Related

How to store same id when editing a post while being admin and not the user the post belongs

I have a forum on my Website and when i access it via admin rights and edit a post i did not make,it changes the stored data from the userid to my admin id hence changing the post as if i made it ,instead of the other person.I dont know how to change it
Since this is my first Website im not sure how to change the code.
I figured i might want a if statement but i already have a construct.
AdminController:
public function storepost(){
{
$user = Auth::user();
// logged in?
if(!$user) {
request()->session()->flash('error', 'No permission!');
return redirect('/');
}
// New post or edit old one
if (request('id')) {
$post = Post::find(request('id'));
} else {
$post = new Post();
}
$dummypost = new Post();
$rules = $dummypost->rules();
// every form filled in ?
$validatedData = request()->validate($rules);
// save post
$post->title = $validatedData['title'];
$post->description = $validatedData['description'];
$post->user_id = $user->id;
$post->save();
//back to forum
return redirect('admin/forum');
}
i want to edit posts it changes them to id 1 which is admin. but it had a id of 2 in the database.i want them to stay 2 even after i edited them
So the problem was that when i edited the post, it changed the user to me (i was the admin) instead of just editing the parts out that i wanted.I fixed that with the if statement:
if (!$user->admin){
$post->user_id = $user->id;
}
I had a boolean value in my database which u can see with admin.so the if statement simply says if user is not admin,
post user_id as user_id.
A simple if check will be okay, notice how on the line above saving your post model you are assigning the user_id to the currently logged in user, we need to restrict that to assign the id only when the user is not Admin, so change that line to this:
if (/* Check if $user is not admin */) {
$post->user_id = $user->id;
//or if you have relationship and it's one to one
$post->user()->associate($user);
}
$post->save();
Or if you don't want to update user_id of your post each time you edit that post as Non admin user you can completely omit that line by removing/commenting it out.
...
// $post->user_id = $user->id;
// Or completely remove it
...
As you said your id 1 is an admin then you can put a condition like as below.
if($user->id != '1'){
$post->user_id = $user->id;
}
It will update user_id only when it's not an admin. If you have boolean "parameter" then code might look like this
if($user->YOURPARAMETER == 1){ //I Assume parameter would be is_admin
$post->user_id = $user->id;
}

How to have multiple selected item in drop-down if saved in id laravel?

I am selecting the multiple id of classes in creating leadtype via explode,how can i get all the selected id of classes in dropdown in edit function
Classes table
id 1 name class one
id 2 name class two
id 3 name class three
Leadtype table
id 1 class_id 1,2,3,
id 2 class_id 1,2
id 3 class_id 2,1
I am saving only id of classes in leadtype table but when i edit i want
all the value selected instead of id
my route
Route::get('admin/leadtypes/form', 'LeadTypesController#form'); add
Route::post('admin/leadtypes/post', 'LeadTypesController#update'); store
Route::get('admin/leadtypes/form/{id}', 'LeadTypesController#editForm'); edit
Add function
public function form() {
$classes = Classes::pluck('name','id');
return view('leadtypes.form',$data,compact('classes'));
}
My store/update function
public function update(Request $request)
{
$data = \Input::except(array('_token')) ;
$rule=array(
'name' => 'required',
);
$validator = \Validator::make($data,$rule);
if ($validator->fails())
{
return redirect()->back()->withInput()->withErrors($validator->messages());
}
$inputs = $request->all();
if(!empty($inputs['id'])){
$item = LeadTypes::findOrFail($inputs['id']);
}else{
$item = new LeadTypes;
}
if(is_array($request->name)){
$item->name = implode(',', $request->name);
}
$item->status = $inputs['status'];
$item->save();
flash('success','record_added_successfully', 'success');
return redirect('admin/leadtypes');
}
edit function
public function editForm($id)
{
$item = LeadTypes::findOrFail($id);
$data['active_class'] = 'Lead type';
$data['title'] = getPhrase('Lead type');
$classes = Classes::pluck('name','id');
$item->name = explode(',', $item->name);
return view('leadtypes.form',$data,compact('item','classes'));
}
My view dropdown
{!! Form::select('name[]', $classes, !empty($item->name) ? $item->name : explode(',',old('name')) ,['class' =>'form-control ' ,'required'=>'true','multiple'=>'true']); !!}
I think you may be pushing the LaravelCollective Form::() method to a place it's not happy with. It is a bit finicky to start, and there are a few issues with what you have above.
The $item->name is actually a string as stored, I think. If it is set in the DB, it is going to come through to your last line of code as a string:
!empty($item->name) ? $item->name : explode(...)
You need to explode the DB-stored string in the FIRST part of your operation above as well, to get this to match whatever the $classes array is for the second parameter in that same statement. String <--> array won't work, and thus won't ever allow for a value to be selected from the model.
I'm pretty sure this will solve it. However, I would also possibly reconsider your architecture on this. Storing those arrays of IDs in a single field (and a field named singular 'name') is a little confusing, and is also making life difficult for you. Perhaps consider pulling those LeadTypes into their own belongsToMany relationship with their own sub table. Then you can just store the two ids and simplify everything. If that works -- but the above should answer your question.

How to pass id from while loop to controller [laravel]

I'm new to laravel, so I'm searching for how to send a specific id to the controller in order to get data from another table ?
For example
while($shipment = sqlsrv_fetch_array($get_customer_rule,SQLSRV_FETCH_ASSOC)) {
//display some data ......
// inside the loop i will have another query to get data from another table has //relation with shipment table
$id = $shipment['id'];
$customer = "SELECT * FROM [ccctadm].[customer] WHERE id = '$id' ";
$get_customer_info = sqlsrv_query($conn, $customer);
$get_customer_id = sqlsrv_fetch_array($get_customer_info,SQLSRV_FETCH_ASSOC);
$customer_id = $get_customer_id['customerid'];
}
I can't write query in while loop in laravel, so how can I pass shipment id to the controller so I can get customer data related to the shipment
Since you are new to Laravel, maybe you should learn the Laravel way first. Watch this video on how to work with Eloquent and perhaps every other video in that series. https://laracasts.com/series/laravel-from-scratch-2017/episodes/7
Once you get your head around that, you will be able to rewrite your query as
$shipments = Shipement::all();
foreach( $shipments as $shipment ) {
$customer = $shipment->customer;
$customer_id = $customer->id;
}
Even better when you get a bit further with laravel and be able to work with eager loading, you will just do
$shipments = Shipment::with('customer')->get();
And in your view
#foreach($shipments as $shipment)
Customer ID is : {{ $shipment->customer->id }}
#endforeach
You have decided you to work with Laravel. Take advantage of it. It will make everything easier and speed up your development process.
If you want to stick to your raw SQL queries, you can use the query builder
$result = DB::select("SELECT * FROM [ccctadm].[customer] WHERE id = ?", [$id]);
And work with the result

Laravel eloquent update record without loading from database

I'm quite new to laravel and I'm trying to update a record from form's input. However I see that to update the record, first you need to fetch the record from database.
Isn't is possible to something like to update a record (primary key is set):
$post = new Post();
$post->id = 3; //already exists in database.
$post->title = "Updated title";
$post->save();
Post::where('id',3)->update(['title'=>'Updated title']);
You can simply use Query Builder rather than Eloquent, this code directly update your data in the database :) This is a sample:
DB::table('post')
->where('id', 3)
->update(['title' => "Updated Title"]);
You can check the documentation here for more information: http://laravel.com/docs/5.0/queries#updates
The common way is to load the row to update:
$post = Post::find($id);
In your case
$post = Post::find(3);
$post->title = "Updated title";
$post->save();
But in one step (just update) you can do this:
$affectedRows = Post::where("id", 3)->update(["title" => "Updated title"]);
Use property exists:
$post = new Post();
$post->exists = true;
$post->id = 3; //already exists in database.
$post->title = "Updated title";
$post->save();
Here is the API documentation: http://laravel.com/api/5.0/Illuminate/Database/Eloquent/Model.html
You can also use firstOrCreate OR firstOrNew
// Retrieve the Post by the attributes, or create it if it doesn't exist...
$post = Post::firstOrCreate(['id' => 3]);
// OR
// Retrieve the Post by the attributes, or instantiate a new instance...
$post = Post::firstOrNew(['id' => 3]);
// update record
$post->title = "Updated title";
$post->save();
Hope it will help you :)

Symfony JSON output including field name

I'm trying to pull a value from my DB in the field 'action', it is a JSON string however I'm storing it as a single value for now, this is it:
'command'=>'get','target'=>'location'
However when I pull it from the DB it includes the field name, which I don't want, see below:
[{"action":"'command'=>'get','target'=>'location'"}]
My code is here:
$em = $this->getDoctrine()->getManager();
$query = $em->createQueryBuilder();
$q = $query->select('z.action')
->from('AppBundle:ZeusUsers', 'z')
->where('z.id = ?1')
->setParameter(1, $id)
->getQuery();
$action = $q->getResult();
return new Response(json_encode($action));
So I just need to know how to grab the field value not including the field name?
try this method getSingleScalarResult()
but remember that if it wouldn't find anything it will throw exception
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#single-scalar-hydration
You want to use getSingleResult() instead of getResult() to get value of your field. It will throw exception if there are no results found or there are more than one result (setMaxResults(1) will remedy this part) though.
https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L802

Categories