Laravel 4: How to use auth.php to fit two models? - laravel-4

I knew the Auth::attempt method is correspond the app/config/auth.php which specifies which model should be used.
I have a problem,how can I do if I have two model that want to be validated?
For example ,I have a Administrator table,And also a User's table.
Can somebody help if you can understand what I'm saying?
Thanks...

You can make any complex login by using the Auth::loginUsingId method, and using the query builder. For instance:
if (/*Any complex validation result*/) {
Auth::loginUsingId( /*the id you want*/ );
//.....
Session::put('some_var',$some_value);
//.....
return Redirect::to('/some_path');
} else {
return Redirect::back()
->withInput()
->with('message', 'Error');
}
Also you need to set in your file app/config/auth.php the driver value to database instead of eloquent by default.

Related

The Laravel $model->save() response?

If you are thinking this question is a beginner's question, maybe you are right. But really I was confused.
In my code, I want to know if saving a model is successful or not.
$model = Model::find(1);
$model->attr = $someVale;
$saveStatus = $model->save()
So, I think $saveStatus must show me if the saving is successful or not, But, now, the model is saved in the database while the $saveStatus value is NULL.
I am using Laravel 7;
save() will return a boolean, saved or not saved. So you can either do:
$model = new Model();
$model->attr = $value;
$saved = $model->save();
if(!$saved){
//Do something
}
Or directly save in the if:
if(!$model->save()){
//Do something
}
Please read those documentation from Laravel api section.
https://laravel.com/api/5.8/Illuminate/Database/Eloquent/Model.html#method_getChanges
From here you can get many option to know current object was modified or not.
Also you can check this,
Laravel Eloquent update just if changes have been made
For Create object,
those option can helpful,
You can check the public attribute $exists on your model
if ($model->exists) {
// Model exists in the database
}
You can check for the models id (since that's only available after the record is saved and the newly created id is returned)
if(!$model->id){
App::abort(500, 'Some Error');
}

Laravel Gate User parameter with eager loading relationship

As far as i know, the $user paramater on Laravel's Gate by default will returning instance of user credentials object which came from EloquentServiceProvider (not from User Model).
Gate::define('create-something', function ($user) {
// Code
}
But, how to add eager loading of relationship on it ? Lets say i have relationship called stuff on User Model, so i want to access it like so :
Gate::define('create-something', function ($user) {
dd($user->stuff);
}
Maybe easiest solution is by passing another parameters which came from Models\User , but it seems duplicating/redundant considering the $user parameter already there by default.
Is the another way to achieve this ?
Add notes : Stuff is many to many relationship
you can do something like this:
Gate::define('create-something', function ($user) {
$user->load('stuff');
dd($user->stuff);
}

How to assert that Laravel Controller returns view with proper data?

I need to know how to assert that Laravel Controller returns view with proper data.
My simple controller function:
public function index() {
$users = User::all();
return view('user.index', ['users' => $users]);
}
I am using functions such as assertViewIs to get know if proper view file is loaded:
$response->assertViewIs('user.index');
Also using asserViewHas to know that "users" variable is taken:
$response->assertViewHas('users');
But I do not know how to assert if retrieve collection of users contain given users or not.
Thanks in advance.
In tests I would use the RefreshDatabase trait to get a clean database on each test. This allows you to create the data you need for that test and make assumptions on this data.
The test could then look something like this:
// Do not forget to use the RefreshDatabase trait in your test class.
use RefreshDatabase;
// ...
/** #test */
public function index_view_displays_users()
{
// Given: a list of users
factory(User::class, 5)->create();
// When: I visit the index page
$response = $this->get(route('index'));
// Then: I expect the view to have the correct users variable
$response->assertViewHas('users', User::all());
}
The key is to use the trait. When you now create the 5 dummy users with the factory, these will be the only ones in your database for that test, therefore the Users::all() call in your controller will return only those users.

laravel using validation request with except method

I am using request validation as
php artisan make:request ClientRequest
As you can see, on client edit form if password field is not empty I am able to use $request->validated() method on database update,
However if password field empty(user dont want to change password),
I am not able to use $request->except('password')->validated() method.
I use $request->except() method due to this situation.
Does this pose a security problem?
public function update(ClientRequest $request, Client $client)
{
$validated = $request->validated();
if($request->filled('password') )
{
Client::whereId($client->id)->update($validated);
}else{
Client::whereId($client->id)->update($request->except('password'));
}
return redirect('/clients')->with('success', 'success');
}
Client::whereId($client->id)->update($request->except('password'));
That line is does pose a big security problem especially if you are relying on validation to set fields rather than the fillable attribute. $request->except('password') will return all the other fields that the user submitted so if the user had added something like is_admin => true in the request, you'll end up setting it on the db if it exists.
You can use \Illuminate\Support\Arr::except() on the validated data to make sure that you are only getting the data you expect. That would change the that particular line to
Client::whereId($client->id)->update(\Illuminate\Support\Arr::except($request->validated(), 'password'));
PS: You already have the client through route model binding so you don't need to query it you can update that client directly i.e
$client->update(\Illuminate\Support\Arr::except($request->validated(), 'password'));
You are validating all fields sent to update() in both scenarios.
You would have had an issue if you sent the password field in both cases, but only validated it in one of them. That's not the case.
So looks fine to me from that perspective.

How to acces is_* property in laravel model?

I am working with laravel 4.2 and have table in db with property is_active.
When I try to access this model property:
$model->is_active
I am getting following error:
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
So question is how to access this property?
Please do not recommend to rename this field in the database if possible because this is already existing database in production.
Here is my model class:
class Position extends \Eloquent {
protected $table = "hr_positions";
protected $fillable = ['slug', 'info_small', 'info_full', 'is_active', 'start_date', 'end_date', 'tags', 'user_create_id', 'user_update_id'];
use \MyApp\Core\StartEndDateTrait;
public function postulations(){
return $this->hasMany('Postulation', 'position_id', 'id');
}
}
Latest notice:
All this error ocurrs on a page where I am creating my entity. In the controller before forwarding to the page I am doing:
$position = new \Position();
and then, for example, following code produce error as well:
dd(($position->getAttribute('is_active')));
but if I replace $position = new \Position(); with
$position = \Position::first();
error is gone?
What is going on here?????
Laravel does a lot of magic behind the scenes, as in, calls a lot of php magic methods.
If a called property is not defined, __call is invoked which in Eloquent calls getAttribute().
Steps taken by getAttribute($key) are
Is there a database field by this key? If so, return it.
Is there a loaded relationship by this key? If so, return it.
Is there a camelCase method of this key? If so, return it. (is_active looks for isActive method)
Returns null.
The only time that exception is thrown is in step 3.
When you create a new instance, eloquent has no idea what kind of fields it has, so if you have a method by the same name, it will always throw a relation error, this seems to be the case in both Laravel4 and Laravel5.
How to avoid it? Use the getAttributeValue($key) method. It has no relation checks and returns null by default.
Alternatively you can also add a get mutator for your field.
I have found a hack for this. Still not ideal but at least I have some solution. Better any than none.
So This code produce problem:
$position = new \Position();
if($position->is_active){
//
}
and this one works fine, this is solution even hacky but solution:
$position = new \Position(['is_active' => 0]);
if($position->is_active){
//
}
I will wait if someone give better, cleaner solution. If no one comes in next few days I will accept mine.

Resources