Laravel How to update value to another column in another table? - laravel

I have two tables named 'users' and 'requests'. In requests table, i want to update users emp_status to 'Admin' and at the same time at table 'users' too.
Here is my controller:
public function update(Request $request, $id)
{
$status = "Admin";
$admin = DB::table('users')
->where('emp_no', $id)
->update(array('emp_status'=>$status));
$forms = Requests::find($id);
$forms->emp_no = $request->get('emp_no');
$forms->emp_name = $request->get('emp_name');
$forms->email = $request->get('email');
$forms->department = $request->get('department');
$forms->emp_status = $request->get('emp_status', $admin);
$forms->justification = $request->get('justification');
$forms->save();
return redirect('admins.request')->with('Success','Employee has been changed to admin!');
}
Requests Model:
class Requests extends Model
{
protected $fillable = [
'emp_no','emp_name','email','emp_status','department','justification'
];
public function User(){
return $this->hasMany('App\Requests');
}
}
User Model:
protected $fillable = [
'emp_no', 'emp_name', 'emp_contact','gender','email','password'
];
public function Requests(){
return $this->hasOne('App\Requests');
}
When i select the 'Admin' option in the form and click approve, it should update the two tables at the same time according to emp_no. Here is the screenshot.
The Form Details blade file
How should i go about it?

Let's assume the <select> in your blade file is defined like this:
<select id="status" name="status">
<option value="Admin">Admin</option>
<option value="Normal">Normal</option>
</select>
Then in your controller you call it with this $request->status
But since your updating two tables at the same time, you should enclose the inside of the updating method with a transaction scope, so that way if any error happens during the process it would rollback:
DB::transaction(function () use ($id, $request){
$admin = DB::table('users')
->where('emp_no', $id)
->update(array('emp_status'=>$request->status));
$forms = Requests::find($id);
$forms->emp_no = $request->get('emp_no');
$forms->emp_name = $request->get('emp_name');
$forms->email = $request->get('email');
$forms->department = $request->get('department');
$forms->emp_status = $request->get('status');
$forms->justification = $request->get('justification');
$forms->save();
});

Related

I am trying to update data without page reload using live wire

Hi I am making a Private chat Application In Livewire but the Thing is When i Insert a message don't show Unless I reload the Page please help me how can i resolved that ? thank u.
I am using Livewire Full-Page Components here is the Code
Note :- I am using this render function inside viewMessage function but data is not updated without page relaod.
this will load the all the conservation message
$this->render();
app\Http\Livewire\Messaging.php
class Messaging extends Component
{
public $body;
public $searchTerm;
public $selectedUser;
public function mount(){
$this->selectedUser =User::where('id','!=',Auth::user()->id)
->first();
}
public function render()
{
$searchTerm = '%'.$this->searchTerm.'%';
if($searchTerm){
$user= User::where('id', '!=', Auth::user()->id)
->where('user_type',1)
->where('email', 'like', $searchTerm)
->with('messages')
->get();
}
$conservation = Message::query()
->where('sender_id', Auth::user()->id)
->where('receiver_id', $this->selectedUser->id)
->orWhere('receiver_id', Auth::user()->id)
->where('sender_id', $this->selectedUser->id)
->with('sender')
->with('receiver')
->get();
return view('livewire.messaging',[
'users' => $user,
'conservation' =>$conservation
]);
}
public function viewMessages($userId){
$this->selectedUser = User::findorFail($userId);
$senderExist = Message::where('sender_id',$this->selectedUser->id)->exists();
if($senderExist){
$message = Message::where('sender_id',$this->selectedUser->id)->orderBy('receiver_id','Desc')->get();
foreach($message as $value){
$value->notification = "0";
$value->save();
}
}
}
public function sendMessages(){
Message::create([
'receiver_id' => $this->selectedUser->id,
'sender_id' => Auth::user()->id,
'body' => $this->body,
]);
$this->reset('body');
$this->viewMessages($this->selectedUser->id);
$this->render(); //this will load the all the conservation message
}
}
resources\views\livewire\messaging.blade.php
<form wire:submit.prevent="sendMessages" action="#" >
<div class="position-absolute bottom-0 col-md-12 pe-3">
<div class="input-group comment-box p-3">
<input wire:model.defer="body" type="text" class="form-control"
placeholder="Type Message ..." aria-label="Aa" aria-describedby="button-addon2" required>
<button class="btn btn-outline-secondary py-0 px-3" type="submit" id="button-addon2"><i class='bx bx-send fs-4'></i></button>
</div>
</div>
</form>
I personally would not suggest loading in data on every single render. Livewire is able to hydrate previously fetched models and collections, which takes away the strain of reloading it from your database each render. I personally would write your component as such:
use Illuminate\Support\Collection;
class Messaging extends Component
{
public $body = '';
public $searchTerm = '';
public $selectedUser;
// Assuming you're using PHP 7.4 or above, else remove typehint
public Collection $users;
public Collection $conversation;
// Ensure we validate the data passed
protected $rules = [
'body' => ['required', 'string'],
];
public function mount()
{
$this->selectedUser = User::where('id','!=',Auth::user()->id)->first();
$this->getUsers();
$this->getConversation();
}
public function render()
{
return view('livewire.messaging');
}
public function updated($field)
{
// Only update the users if the search term has changed
if ($field === 'searchTerm') {
$this->getUsers():
}
}
public function viewMessages($userId)
{
$this->selectedUser = User::findorFail($userId);
$senderExist = Message::where('sender_id',$this->selectedUser->id)->exists();
if($senderExist) {
$messages = Message::where('sender_id',$this->selectedUser->id)->orderBy('receiver_id','desc')->get();
foreach($messages as $message){
$message->notification = "0";
$message->save();
}
// Are you saving the messages one by one to trigger model events? If not, use below query to instantly update all of them at once in the database:
// Message::where('sender_id',$this->selectedUser->id)->orderBy('receiver_id','desc')->update([
// 'notification' => 0,
// ]);
}
}
public function sendMessages()
{
// Validate the data as per given rules
$this->validate();
Message::create([
'receiver_id' => $this->selectedUser->id,
'sender_id' => Auth::user()->id,
'body' => $this->body,
]);
$this->reset('body');
$this->viewMessages($this->selectedUser->id);
// Refresh conversation
$this->getConversation();
}
public function getConversation()
{
$this->converstaion = Message::query()
->where('sender_id', Auth::user()->id)
->where('receiver_id', $this->selectedUser->id)
->orWhere('receiver_id', Auth::user()->id)
->where('sender_id', $this->selectedUser->id)
->with('sender')
->with('receiver')
->get();
}
public function getUsers()
{
$query = User::where('id', '!=', Auth::user()->id)
->where('user_type', 1)
->with('messages');
if (! empty($this->searchTerm)) {
$searchTerm = '%'.$this->searchTerm.'%';
$query->where('email', 'like', $searchTerm);
}
$this->users = $query->get();
}
}
The render method gets called by Livewire itself each time something happens, such as a value change of a variable, or after a function was called. You should not call it yourself.
P.S. For Livewire to fully keep track of what is what, I suggest adding wire:key to data rows. For example, on a div that is holding the data to your conversation messages, add wire:key="message-{{$message->id}}". This way, if a data change happens, Livewire knows exactly what date should be changed. Read more about it here
You should use the livewire emite event
https://laravel-livewire.com/docs/2.x/events

Laravel Eloquent update with custom entries

I have u CRUD project, and now I have idea to get update of one table with custom entries.
This is my controller:
public function update($id, Request $request)
{
$data = $request->only(['x', 'y', 'time']);
$device_new = Device_new::where('deviceId', $id)->first();
$device_new->x = $data['x'];
$device_new->y = $data['y'];
$device_new->datetime = $data['datetime'];
$device_new->save();
}
Is it even possible to update x, y, and datetime without edit blade, just update them with some limited values with command on some button?
Like in new controller:
public function update($id, Request $request)
{
$x='47'; $y='16';
$device_new = Device_new::where('deviceId', $id)->first();
$device_new->x = $x;
$device_new->y = $y;
$device_new->save();
}

Why does the old() method not work in Laravel Blade?

My environment is Laravel 6.0 with PHP 7.3. I want to show the old search value in the text field. However, the old() method is not working. After searching, the old value of the search disappeared. Why isn't the old value displayed? I researched that in most cases, you can use redirect()->withInput() but I don't want to use redirect(). I would prefer to use the view(). method
Controller
class ClientController extends Controller
{
public function index()
{
$clients = Client::orderBy('id', 'asc')->paginate(Client::PAGINATE_NUMBER);
return view('auth.client.index', compact('clients'));
}
public function search()
{
$clientID = $request->input('clientID');
$status = $request->input('status');
$nameKana = $request->input('nameKana');
$registerStartDate = $request->input('registerStartDate');
$registerEndDate = $request->input('registerEndDate');
$query = Client::query();
if (isset($clientID)) {
$query->where('id', $clientID);
}
if ($status != "default") {
$query->where('status', (int) $status);
}
if (isset($nameKana)) {
$query->where('nameKana', 'LIKE', '%'.$nameKana.'%');
}
if (isset($registerStartDate)) {
$query->whereDate('registerDate', '>=', $registerStartDate);
}
if (isset($registerEndDate)) {
$query->whereDate('registerDate', '<=', $registerEndDate);
}
$clients = $query->paginate(Client::PAGINATE_NUMBER);
return view('auth.client.index', compact('clients'));
}
}
Routes
Route::get('/', 'ClientController#index')->name('client.index');
Route::get('/search', 'ClientController#search')->name('client.search');
You just need to pass the variables back to the view:
In Controller:
public function search(Request $request){
$clientID = $request->input('clientID');
$status = $request->input('status');
$nameKana = $request->input('nameKana');
$registerStartDate = $request->input('registerStartDate');
$registerEndDate = $request->input('registerEndDate');
...
return view('auth.client.index', compact('clients', 'clientID', 'status', 'nameKana', 'registerStartDate', 'registerEndDate'));
}
Then, in your index, just do an isset() check on the variables:
In index.blade.php:
<input name="clientID" value="{{ isset($clientID) ? $clientID : '' }}"/>
<input name="status" value="{{ isset($status) ? $status : '' }}"/>
<input name="nameKana" value="{{ isset($nameKana) ? $nameKana : '' }}"/>
...
Since you're returning the same view in both functions, but only passing the variables on one of them, you need to use isset() to ensure the variables exist before trying to use them as the value() attribute on your inputs.
Also, make sure you have Request $request in your method, public function search(Request $request){ ... } (see above) so that $request->input() is accessible.
Change the way you load your view and pass in the array as argument.
// Example:
// Create a newarray with new and old data
$dataSet = array (
'clients' => $query->paginate(Client::PAGINATE_NUMBER),
// OLD DATA
'clientID' => $clientID,
'status' => $status,
'nameKana' => $nameKana,
'registerStartDate' => $registerStartDate,
'registerEndDate' => $registerEndDate
);
// sent dataset
return view('auth.client.index', $dataSet);
Then you can access them in your view as variables $registerStartDate but better to check if it exists first using the isset() method.
example <input type='text' value='#if(isset($registerStartDate)) {{registerStartDate}} #endif />

laravel 5.7 how to pass request of controller to model and save

I am trying to pass $request from a function in controller to a function in model.
THis is my controller function:
PostController.php
public function store(Request $request, post $post)
{
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return redirect(route('post.index'));
}
how save data in model Post.php?
I want the controller to only be in the role of sending information. Information is sent to the model. All calculations and storage are performed in the model
Thanks
You can make it even easier. Laravel has it's own helper "request()", which can be called anywhere in your code.
So, generally, you can do this:
PostController.php
public function store()
{
$post_model = new Post;
// for queries it's better to use transactions to handle errors
\DB::beginTransaction();
try {
$post_model->postStore();
\DB::commit(); // if there was no errors, your query will be executed
} catch (\Exception $e) {
\DB::rollback(); // either it won't execute any statements and rollback your database to previous state
abort(500);
}
// you don't need any if statements anymore. If you're here, it means all data has been saved successfully
return redirect(route('post.index'));
}
Post.php
public function postStore()
{
$request = request(); //save helper result to variable, so it can be reused
$this->title = $request->title;
$this->description = $request->description;
$this->save();
}
I'll show you full best practice example for update and create:
web.php
Route::post('store/post/{post?}', 'PostController#post')->name('post.store');
yourform.blade.php - can be used for update and create
<form action='{{ route('post.store', ['post' => $post->id ?? null]))'>
<!-- some inputs here -->
<!-- some inputs here -->
</form>
PostController.php
public function update(Post $post) {
// $post - if you sent null, in this variable will be 'new Post' result
// either laravel will try to find id you provided in your view, like Post::findOrFail(1). Of course, if it can't, it'll abort(404)
// then you can call your method postStore and it'll update or create for your new post.
// anyway, I'd recommend you to do next
\DB::beginTransaction();
try {
$post->fill(request()->all())->save();
\DB::commit();
} catch (\Exception $e) {
\DB::rollback();
abort(500);
}
return redirect(route('post.index'));
}
Based on description, not sure what you want exactly but assuming you want a clean controller and model . Here is one way
Model - Post
class Post {
$fillable = array(
'title', 'description'
);
}
PostController
class PostController extend Controller {
// store function normally don't get Casted Objects as `Post`
function store(\Request $request) {
$parameters = $request->all(); // get all your request data as an array
$post = \Post::create($parameters); // create method expect an array of fields mentioned in $fillable and returns a save dinstance
// OR
$post = new \Post();
$post->fill($parameters);
}
}
I hope it helps
You need to create new model simply by instantiating it:
$post = new Post; //Post is your model
then put content in record
$post->title = $request->title;
$post->description = $request->description;
and finally save it to db later:
$post->save();
To save all data in model using create method.You need to setup Mass Assignments when using create and set columns in fillable property in model.
protected $fillable = [ 'title', 'description' ];
and then call this with input
$post = Post::create([ 'parametername' => 'parametervalue' ]);
and if request has unwanted entries like token then us except on request before passing.
$post = Post::create([ $request->except(['_token']) ]);
Hope this helps.
I find to answer my question :
pass $request to my_method in model Post.php :
PostController.php:
public function store(Request $request)
{
$post_model = new Post;
$saved = $post_model->postStore($request);
//$saved = response of my_method in model
if($saved){
return redirect(route('post.index'));
}
}
and save data in the model :
Post.php
we can return instance or boolean to the controller .
I returned bool (save method response) to controller :
public function postStore($request)
{
$this->title = $request->title;
$this->description = $request->description;
$saved = $this->save();
//save method response bool
return $saved;
}
in this way, all calculations and storage are performed in the model (best way to save data in MVC)
public function store(Request $request)
{
$book = new Song();
$book->title = $request['title'];
$book->artist = $request['artist'];
$book->rating = $request['rating'];
$book->album_id = $request['album_id'];
$result= $book->save();
}

Trying to get property 'id' of non-object laravel

can someone to help me ? i have an error Trying to get property 'id' of non-object laravel while try to show my edit form
this is my controller
public function edit($id)
{
$produk = produk::where('id',$id)->first();
return view('produk.edit',compact('produk'));
}
public function update(Request $request, $id)
{
produk::where('id',$id)
->update([
'nama' => $request->nama,
'id_kategori' => $request->kategori,
'qty' => $request->qty,
'harga_beli' => $request->beli,
'harga_jual' => $request->jual,
]);
return redirect()->route('produk.index');
}
this is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class produk extends Model
{
protected $guarded = ['id','created_at','updated_at'];
public function kategoris()
{
return $this->hasOne('App\kategori', 'id', 'id_kategori');
}
}
and this is my view
<select class="form-control" name="kategori">
<option value="Pilih Kategori"></option>
#foreach ($produk as $k)
<option value="{{ $k->id }}" #if($produk->id_kategori == $k->id) selected #endif>{{$k->nama}}</option>
#endforeach
</select>
Its because of this
$produk = produk::where('id',$id)->first();
this returns an object not an array of object. thats why your getting an error on your view. Instead use:
$produk = produk::where('id',$id)->get();
to return an array of object.
You are trying to foreach trough product properties, but looks like you need to foreach trough collection of categories.
Add categories to view in controller:
public function edit($id)
{
$produk = produk::find($id);
$kategoris = kategori::all();
return view('produk.edit',compact('produk', 'kategoris'));
}
Iterate trough $kategoris (not $produk) in View:
<select class="form-control" name="id_kategori">
<option value="Pilih Kategori"></option>
#foreach ($kategoris as $kategori)
<option value="{{ $kategori->id }}" #if($produk->id_kategori == $kategori->id) selected #endif>{{$kategori->nama}}</option>
#endforeach
</select>
Also, if foreign key is id_kategori, it is better to use name=id_kategori istead of name=kategori
You don't need relation here, because you compare categories ids with id_kategori attribute. But you should replace hasOne to belongsTo in this case.
public function kategoris()
{
return $this->belongsTo('App\kategori', 'id_kategori');
}
The correct way to obtain the value of the arrangement is
$k["id"] and not $k->id
I tried to obtain a field incorrectly with the array, I received the following array
[{"id": 1, "name": "Ivania", "code": 387}, {"id": 2, "name": "Robert", "code": 389}]
Check the array with a foreach
$users = $request->input('users');
foreach($users as $key => $user)
$person = new Person();
//incorrect form
//$person->id = $user->id
//the correct form
$person->id = $user["id"];
$person->name = $user["name"];
$person->code = $user["code"];
$person-> save ();
}

Resources