Is there an efficient way of adding user_id using updateOrCreate? - laravel

I'm trying to add/update responses from a multi-field form using updateOrCreate.
I'm avoiding having to write out the second argument in full for each field in the form by using $request->all. However, this approach so far is precluding me from adding the value for user_id that is needed for the record to be complete. That value (`$userId') is obtained in the controller as shown:
$userId = Auth::user()->id;
$cropid = $request->id;
Crop::updateOrCreate(['id'=>$cropid],$request->all());
Is there a way of retaining the $request->all approach AND adding the user_id value?
Thanks, Tom.

You can use array_merge to generate an array with both data:
$data = array_merge($request->all(), ['user_id' => $userId]);
Then you can use the generated $data in your updateOrCreate method:
Crop::updateOrCreate(['id' => $cropId], $data);

Related

How to get product after insert and update in query builder

I'm trying to get the same result as in Eloquent when create and update will return the model back.
In the case of query builder, how can I return the model when insert returns boolean and update returns the ID of the updated row?!?!?
For example: DB::table('users')->insert( ['email' => 'john#example.com', 'votes' => 0] );
Will return boolean, instead what I am looking for is to get that created user, same behavior with User::create().
DB::table('users')->update() will return the ID of the updated row, again I want the updated row as an object same behavior with User::update().
I know that insertGetId() will give me the ID when I use insert(), but I don't want to make an extra step to use the ID and find the row.
Also, for the update, I don't want to use the ID that update() returns to use it in order to find the row.
Does that make any sense?
Use insertGetId() instead of insert() and then find() the model. For example:
$id = DB::table('users')->insertGetId(['name' => 'Ivanka', 'email' => 'ivanka#ivanka.com']);
$user = User::find($id);
When you are updating you have the id, so just find() it: User::find($id).
Documentation that explains how insertGetId() works: https://laravel.com/docs/5.7/queries#inserts
also, you can use from below code if you want.
find the last insert column:
$last_id = Illuminate\Support\Facades\DB::getPdo()->lastInsertId();
and next:
$user = User::find($last_id);

how to display name from database in laravel

i want to display data from my database
controller
public function generatePDF(Request $request)
{
$id = Auth::user()->id;
$name = User::select("NAME")->where("id", $id)->get();
$pdf = PDF::loadView('generatePDF', ['name'=>$name]);
return $pdf->stream('generatePDF.pdf');
}
blade
<h2>{{name}}</h2>
result
[{"NAME":"name_from_database"}]
can i display without [{"name":}], so just the value of data (name_from_database) ?
Simple use find like this
$name = User::find($id)->name;
Or direct from auth
$name = \Auth::user()->name;
To get logged in user id you can use \Auth::id()
you can use:
$user_id = User::findOrFail($id)->first();
$name=$user_id->name;
test the laravel log file:
\Log::info($name);
Use first() instead of get(), because get() will return an array and first() will return the object.
DRY Code line no.1 and no.2. simple use:
$name = auth()->user()->name;
to get the name of the currently authenticated user.
Send $name to you view is fine
$pdf = PDF::loadView('generatePDF', ['name' => $name]);
Correct your code in blade file
{{ name }} -> {{ $name }}
I hope this might help you. :)
Hello Aldi Rostiawan,
$nameGet = User::select("NAME")->where("id", $id)->get();
$nameFirst = User::select("NAME")->where("id", $id)->first();
Here in both line of code the difference is only Get and First.
Get method returns an Array of objects. So for example if the query apply on many records then the code will give you many objects in an array. Or if query will be true for only one record then also it will return an array with one object.
If you know that id is primary key of he table then only one record will be fetched then you can use First function instead if Get method.
First function always return an Object. In case if query apply on many records then also first method will return you only first record as an Object.
And it seems that you have required an Object only.
You should try this:
Controller
public function generatePDF(Request $request)
{
$id = Auth::user()->id;
$rsltUser = User::where("id", $id)->first();
$pdf = PDF::loadView('generatePDF', ['rsltUser'=>$rsltUser]);
return $pdf->stream('generatePDF.pdf');
}
blade
<h2>{{$rsltUser->name}}</h2>
use VALUE() to display name only.
in your case:
<h2>{{$rsltUser->value('name')}}</h2>
your name variable is an array containing a single object with a NAME attribute .. so to diplay that value, you should change your script to
<h2>{{name[0]['NAME']}}</h2>

Laravel 4: Unique Validation for Multiple Columns

I know this question has been asked earlier but i did not get relevant answer.
I want to know that how can i write a rule to check uniqueness of two columns. I have tried to write a rule like:
public $rules = array(
"event_id"=>"required",
"label"=>"required|unique:tblSection,label,event_id,$this->event_id",
"description"=>"required"
);
In my example i need to put validation so that one label could be unique for a single event id but may be used for other event id as well. For Example i want to achieve:
id event_id label description
1 1 demo testing
2 2 demo testing
In the rule defined above, somehow i need to pass current selected event_id so that it could check whether the label does not exist in the database table for selected event_id but i am getting syntax error like:
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"syntax error, unexpected '\"'","file":"\/var\/www\/tamvote\/app\/modules\/sections\/models\/Sections.php","line":39}}
Note: I don't want to use any package but simply checking if laravel 4 capable enough to allow to write such rules.
The answer from Mohamed Bouallegue is correct.
In your controller for the store method you do:
Model::$rules['label'] = 'required|unique:table_name,label,NULL,event_id,event_id,' .$data['event_id'];
where $data is your POST data.
And for the update method you do:
$model = Model::find($id);
Model::$rules['label'] = 'required|unique:table_name,label,NULL,event_id,event_id,'.$data['event_id'].',id,id'.$model->id;
where $data is your PUT/PATCH data, $model is the record you are editing and id is the table primary key.
I didn't try this before but I think if you get the event_Id before validating then you can do it like this:
'label' => 'unique:table_name,label,NULL,event_id,event_id,'.$eventId
//you should get the $eventId first
If you want to declare your validation rules statically you can do this as well. It's not the most efficient since it checks the database for each value.
protected $rules = [
'user_id' => 'unique_multiple:memberships,user_id,group_id',
'group_id' => 'unique_multiple:memberships,user_id,group_id',
]
/**
* Validates that two or more fields are unique
*/
Validator::extend('unique_multiple', function ($attribute, $value, $parameters, $validator)
{
//if this is for an update then don't validate
//todo: this might be an issue if we allow people to "update" one of the columns..but currently these are getting set on create only
if (isset($validator->getData()['id'])) return true;
// Get table name from first parameter
$table = array_shift($parameters);
// Build the query
$query = DB::table($table);
// Add the field conditions
foreach ($parameters as $i => $field){
$query->where($field, $validator->getData()[$field]);
}
// Validation result will be false if any rows match the combination
return ($query->count() == 0);
});
Like Sabrina Leggett mentioned, you need to create your own custom validator.
Validator::extend('uniqueEventLabel', function ($attribute, $value, $parameters, $validator) {
$count = DB::table('table_name')->where('event_id', $value)
->where('label', $parameters[0])
->count();
return $count === 0;
}, 'Your error message if validation fails.');
You can call your validator by adding the following line to your rules:
'event_id' => "uniqueEventLabel:".request("label")
If you need more fields, you could add a new where clause to the sql statement.
(Source: edcs from this answer)
As you I was looking for hours to do that but nothing worked, I test everything ... suddenly the randomness of the doc I came across this:
'email' => Rule::unique('users')->where(function ($query) {
return $query->where('account_id', 1);
})
https://laravel.com/docs/5.5/validation#rule-unique
and it works perfectly and moreover it is very flexible :)

Laravel Eloquent - update() function

Laravel's Eloquent update() function returns a boolean, and not the updated entry. I'm using:
return User::find($id)->update( Input::all() )
And this returns only a boolean. Is there a way I can get the actual row, without running another query?
I think that's the behaviour that you want:
$user = User::find($id)->fill(Input::all());
return ($user->update())?$user:false;
I hope it works fine for you.
Another approach can is to use the laravel tap helper function.
Here is an example to use it for updating and getting the updated model:
$user = User::first();
$updated = tap($user)->update([
"username" => "newUserName123"
]);
tap($user) allows us to chain any method from that model. While at the end, it will return the $user model instead of what update method returned.

Laravel 4: how to update multiple fields in an Eloquent model?

How can I update multiple fields in an Eloquent model? Let's say I got it like this:
$user = User::where("username", "=", "rok");
And then I have all these model parameters:
$new_user_data = array("email" => "rok#rok.com", "is_superuser" => 1, ...);
I can't just do:
$user->update($new_user_data);
What's the proper way? I hope not a foreach.
The following does work, however. Is this the way to go?
User::where("id", "=", $user->id)->update($new_user_data);
The problem with the last one (besides it being clunky) is that when using it from an object context, the updated fields are not visible in the $this variable.
The method you're looking for is fill():
$user = User::where ("username","rok"); // note that this shortcut is available if the comparison is =
$new_user_data = array(...);
$user->fill($new_user_data);
$user->save();
Actually, you could do $user->fill($new_user_data)->save(); but I find the separate statements a little easier to read and debug.
You are looking for this:
$user = User::where("username","rok")
->update(
array(
"email" => "rok#rok.com",
"is_superuser" => 1,
// ..
)
);
Refer : http://laravel.com/docs/4.2/eloquent#insert-update-delete
I should suggest to use shorter code, such as
$new_user_data=array('a'=>'n','b'=>'m');
$user=User::whereUsername('rok');//camelCase replaces "=" sign
$user->fill($new_user_data)->save();
Or even shorter
$new_user_data=array('a'=>'n','b'=>'m');
User::whereUsername('rok')->update($new_user_data);//camelCase replaces "=" sign
I believe the last statement is easier to debug and looks nicer.
Warning: If your table contains many users named 'rok' both mentioned statements will update all those registers at once. You should always update registers with the id field value.
Try this,
// took required data out of the request
$postData = request(
[
'firstName',
'lastName',
'address1',
'address2',
'address3',
'postcode',
'phone',
'imageURL',
]
);
// persisted it to the database
DB::table('users')
->where('id', auth()->user()->id)
);

Resources