How to get specific model profile after authorization? - laravel

Here are some user profiles like: DoctorModel, UserModel, ClinicModel.
Each has own set of fields in database.
How to add concrete model in global scope when user is authorized to be able get model fields across all application.
For exmaple if user authorized as clinic I want to get from this model field nameClinic everywhere.
Now by defaul I got UserModel form Auth::user()

IMO this is somewhat a wrong approach. You can maintain a UserModel for all types of Users and the details that might change can be held on other Models.
For example, the ClinicModel belongsTo relationship on UserModel and holds the details specific to the clinic over there.

Related

The right way to receive related data in Laravel?

Here are some models:
UserModel
SpecializationModel
UserSpecializationModel
I need to recieve authorized user's specialization. I can do that:
$specializations = UserSpecialization::where("user_id", Auth::user()->id)->get();
Also I can do this through the UserModel model using relation hasMany() specializations().
When to use first case and the second?
$specializations = Auth::user()->specializations();
Do I need a model UserSpecializationModel?
In general you don't need UserSpecilizatonModel, in most situations you wont access data directly from that table, you'll either do it through user or specialization model.
Check also https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns for accessing data from pivot table.

One model, one table different user types and different controllers, how to handle policies?

I have one model user and one table against that model users I have different roles for user as patient, hospital and so on, each user have different fields and values to enter during registration so I have created different routes and controllers for different roles.
Now I'm facing problem during authorization process how I can authorize. I have only one model user so I can create only one policy called UserPolicy and use the $this->authorize method in the UserController.
I have also other controllers as PatientController, HospitalController which all bound to the one table and model called user and fetching the record only based on the user type. Now how can I create the policies for them and use the $this->authorize method in the Hospital, Patient controllers?
you are using the same table and you require different data from each kind if user ?
anyway if that the situation , you can create a type field in the users table , then create 2 middlewares , in your middleware check the type of the user then throw an exception or make him pass

asp.net core Identity user customization

Detail
I am developing web application in asp.net core with Identity. now in my application I have two kind of user. Customer and Partner both have different profile information and login scenario.customer can login from simple signup from web page but partner can signup from different view with different mandatory fields.
Problem
How can I design Schema.
what are the good practices in this case.
What are the drawback.
Code
This is what I have done so far
public class ApplicationUser : IdentityUser
{
public CustomerProfile CustomerProfile { get; set; }
}
Use inheritance:
public class ApplicationUser : IdentityUser {}
public class Customer : ApplicationUser
{
// Customer-specific properties
}
public class Partner : ApplicationUser
{
// Partner-specific properties
}
By default, this will be implemented via STI (single-table inheritance). That means you'll have just your standard AspNetUsers table containing columns for the properties on ApplicationUser and all derived types. A discriminator column will be added to indicate which type was actually saved, which will then be used to instantiate the right type when queried.
For the most part, this works just fine. The one downside is that properties on derived classes must be nullable. The reason is simple: it would be impossible to provide values for Customer columns while saving a Partner and vice versa. However, the properties only need be nullable at the database-level. You can still require that they be set in forms and such via a view model.
The alternative is to use TPT (table-per-type). With this approach, you'll get AspNetUsers, but also Customers and Partners tables as well. However, the tables for the derived types will have columns corresponding only to the properties specific to that type and a foreign key back to AspNetUsers. All common properties are stored there. With this, you can now enforce columns have values at the database-level, but querying users will require a join. To use TPT, you simply add the Table attribute to your class, i.e. [Table("Customers")] and [Table("Partners")], respectively.
The one important thing to keep in mind with using inheritance, though, is that you need to work with the type you actually want to be persisted. If you save an ApplicationUser instance, it will be an ApplicationUser, not a Customer or Partner. In this regard, you need to be careful with using the correct types with things like UserManager which generically reference the user type. Even if you create an instance of Customer, if you save it via an instance of UserManager<ApplicationUser>, it will upcast to ApplicationUser and that is what will be persisted. To create a new Customer, you'll need an instance of UserManager<Customer>. Likewise, for partners.
However, this also works to your benefit, as if you attempt to look up a user from an instance of UserManager<Customer> for example, you will only find them if they are in fact a Customer. In this way, it makes it trivially simple to have separate portals where only one or the other can log in, as you've indicated that you want.

Database schema for kind of Hospital Management in Laravel

I am trying to start an application but it's not for managing hospital, it will be for doctors and patients. Where there will be multiple types for users will be able to login such as Doctor, Patients/Guardians.
Doctors can have multiple clinics at multiple locations and doctor can manage patient records. Once the patient account has been created by doctor then patient can take appointment from doctor or update his appointment status and many more stuff will be there next.
The thing is how to go with the ERD?
I will have
User //User accounts used to login in to the system
Doctor
Patient
Guardian
Role
Permission
These are the models I have currently created, but they don't seem right to me.
Should I remove role columns as I already have different tables for different pre-defined roles?
Or should it be there? But how to manage permissions on users if no roles table is there?
Also, most importantly, how to go with one to one with users? I mean should I go and create functions in user model such as:
public function doctor(){}
public function guardian(){}
public function patient(){}
Or is there a better approach to follow?
If they are all users, you can extend different users from a base user model.
If they require different columns in database, consider single table inheritance.
If roles are static, I would create a class called UserType and have constants of each user type mapped to an integer. In the database, the user table will have a type column which is mapped to this integer.
For example:
class UserType {
const DOCTOR = 1;
}
In your application you'll be able to check the type of user by doing $user->type === UserType::DOCTOR
In the Eloquent itself, you can extend newFromBuilder method to check the type attribute and return the child class (like Doctor) instead of User. So even when you do $user = User::find(1);, you'll still get the class Doctor.
When creating users, you can just create Doctor itself but make sure in __construct to set the appropriate type attribute.
So now you have a base User class, your shared functionality can go here. Specialised methods such as relation to clinics can go in the Doctor class.
This is somewhat similar to the above: https://github.com/Nanigans/single-table-inheritance

Help dealing with data dependency between two registration forms

I have a tricky issue here with a registration of both a user and his/her pet. Both the user and the pet are treated as separate entities and both require separate registration forms. However, the user's pet has to be linked to the user via a foreign key in the database. The process is basically that when a new user joins the site, firstly they register their pet, then they register themselves. The reason for this order is to check their pet's eligibility for the site (there are some criteria to be met) first, instead of getting the user to sign up only to then find out their pet is ineligible. It is this ordering of the form submissions which is causing me a bit of a headache, as follows...
The site is being developed with an MVC framework, and the User registration process is managed via a method in a User_form controller, while the pet registration process is managed via a method in the Pet_form controller.
The pet registration form happens first, and the pet data can be saved without the owner_id at this stage, with the user id possibly being added (e.g by retrieving pet's id from session) following user registration. However, doing it this way could potentially result in redundant data, where pet records would be created in the database, but if the user doesn't actually register themselves too, then the pets will be ownerless records in the DB.
Other option is to serialize the new pet's data at the pet registration stage, don't save it to the DB until the user fills out their registration form. Once the user is created, i can pass serialised data AND the owner_id to a method in the Pet Model which can update the DB. However, I also need to set the newly created $pet to $this->pet which I then access for a sequence of other related forms. Should I just set the session variable in the model method? Then in the Pet controller constructor, do a check for pet stored in session, if yes, assign to $this->pet...
If this makes any sense to anybody and you have some advice, i'd be grateful to hear it!
Here's a slightly left-field solution (which may or may not work depending on your situtation:
Require the user to enter a valid email address upon pet registration, and then link the user with the pet upon user registration by matching email address (or hash of email address).
If you're left with dangling pet references, you could send an email to the pet owner saying "I'm about to delete your pet" after a month (if there's no associated user id), or something like that.

Resources