Relationships Inside Laravel - database

I'm trying to find out how to work with the following relationship. I have a users table with a few fields like id, username, name, role_id. I have a roles table that has an id, and name field.
All users have one role and roles belong to all users so that more than one user can have the same role obviously. I have the following in the corresponding models.
I'm trying to figure out what I need to do so that when I do a call for all users it will get the name of the role and show it instead of the role_id.
class Role extends Eloquent {
public function users()
{
return $this->hasMany('User'); // this will get all the users that have a role_id that matches it's own id
}
}
class User extends Eloquent implements UserInterface, RemindableInterface {
public function role()
{
return $this->belongsTo('Role'); // this will select the role by 'role_id' and return an instance
}
}
Any other ideas?

You can use eager loading, To get the name of the role you just call the function you defined in user model.
$user->role->name;
see Laravel docs for more Information.

Related

Microsoft graph api returning NULL in Department field

I have given all required permissions for retrieving user info from Azure active directory like User.Read.All and User.Read but still getting Department and EmployeeId field as NULL
code used:
public Microsoft.Graph.User GetUser(ref GraphServiceClient graphServiceClient, string UserId)
{
return graphServiceClient.Users[UserId].Request().GetAsync().Result;
}
According to the documentation both department and employeeId are returned only on $select.
Use Select method and specify those two properties. If you need to return more properties, they need to be specified in Select. Without using Select, Graph API return only default set of properties.
public Microsoft.Graph.User GetUser(ref GraphServiceClient graphServiceClient, string UserId)
{
return graphServiceClient.Users[UserId]
.Request()
.Select("department,employeeId")
.GetAsync()
.Result;
}
Resources:
Select parameter

Filter via condition on one relation and eager load another relation records

I have this code I want to get list users with a role of teacher where each teacher will have one object for the personal detail one object for the school detail
public function index(){
$teachers = User::whereHas('roles' , function($q){$q->where('name','isTeacher');})->get();
foreach($teachers as $teacher){
$teacher_id = $teacher->id;
$teacherinSchool = School_Teachers::where('user_id', $teacher_id)->first();
$teacherinSchool = $teacherinSchool->school_id;
$School = School::where('id', $teacherinSchool)->first();
return response(['teacher'=>$teacher, 'school'=>$School]);
}
}
this is what i got but i am expecting to have more that one teacher but it takes the first teacher in the list and display the objects
output in the postman
i have 5 models involved here User model, Role model, User_Role model, school model and school_teacher model
Few things to point out
You are doing queries within a loop (foreach) not good for performance.
Having return response() within foreach loop hence only 1 Teacher record is available
You are getting just the first record for School_Teachers & School
For what you are trying to do can be done more efficiently as under
public function index()
{
$teachers = User::whereHas('roles', fn($query) => $query->where('name', 'isTeacher'))->get();
$schoolIds = School_Teachers::whereIn('user_id', $teachers->pluck('id')->toArray())->pluck('id')->toArray();
$schools = School::whereIn('id', $schoolIds)->get();
return response()->json(['teachers' => $teachers, 'schools' => $schools]);
}
However that is also not optimal, still can be better
Define a relation on User model to link it to School model via School_Teachers (many-to-many)
Then in a single query you can get User(s) which have role of isTeacher with their School
For eg: Say you have a table school_teachers which has columns for user_id, school_id (kind of pivot table) where each record can be uniquely identified by ['user_id', school_id'] composite key - unique index on database table.
Then you can define direct (many-to-many) relation between User and School
//User model
public function schools()
{
return $this->belongsToMany(School::class, 'school_teachers', 'user_id', 'school_id');
}
//School model
public function teachers()
{
return $this->belongsToMany(User::class, 'school_teachers', 'school_id', 'user_id');
}
In controller you can do
public function index()
{
$teachers = User::with('schools')
->whereHas(
'roles',
fn($query) => $query->where('name', 'isTeacher')
)
->get();
return response()->json(['teachers' => $teachers]);
}
Laravel Docs - Eloquent Relationships - Many-to-Many

database modeling: null foreign keys by entity type

I need some help designing my database relationships.
I have these tables: documents, companies, individuals and users. A document can be internal or external.
If it is external, it can be signed by a company or an individual.
If it is internal it has to be signed by a user.
In any case, the document is signed by a single entity (company, individual or user). I was thinking of creating the documents table in the following way:
documents
----------
id_document
...
type
id_user
id_company
id_indiv
where type can be 0: internal, 1: external and id_user, id_company, id_indiv are foreign keys of the respective tables and can be null. Is this logic okay? Can someone suggest me a better idea?
Laravel's Eloquent ORM provides the Polymorphic relationship to handle this kind of problem.
To be more specific, you can place two fields; documentable_type and documentable_id inside your document table. And then add these relationship methods to each model;
class Document extends Model
{
/**
* Get the owning imageable model.
*/
public function signer()
{
return $this->morphTo();
}
}
class User extends Model
{
/**
* Get the documents signed by this user.
*/
public function documents()
{
return $this->morphMany('App\Models\Document', 'documentable');
}
}
class Company extends Model
{
/**
* Get the documents signed by this company.
*/
public function documents()
{
return $this->morphMany('App\Models\Document', 'documentable');
}
}
class Individual extends Model
{
/**
* Get the documents signed by this individual.
*/
public function documents()
{
return $this->morphMany('App\Models\Document', 'documentable');
}
}
Then you can use the following snippets;
$document->signer; // This returns either user or company or individual
$company->documents; // This returns a collection of document models which is signed by this company
$individual->documents;
$user->documents;
For more details, see this link; https://laravel.com/docs/8.x/eloquent-relationships#polymorphic-relationships

I to assign a default account to a custom object using Visualforce page

I am new to salesforce development. I am trying to create a visualforce page which helps to insert a new record into the custom object. Custom object has master-detail relationship with account. I am having issue when assiging a default value to the Account. The account already exists in the accounts table. Here is the Apex class I am trying.
public class RelatedAccount{
public Account parent {get; set;}
public RelatedAccount(ApexPages.StandardController controller){
Transaction__c child = (Transaction__c)controller.getRecord();
if (child.Account__c != null) { parent = [Select ID,Name FROM Account WHERE Account.Name = :'1Company Inc.,' LIMIT 1];
child.Account__c = parent;
}
}}
I am getting the error : "Illegal assignment from Account to Id"
Thanks In advance.
This should work:
child.Account__c = parent.Id
In your case you try to put the "whole" account object object into the Lookup field. But this just needs the Id of the parent account.

access model class inside entity class of other model

I am using CakePHP 3.4+
I have written an application with multi level membership.
The Pro members will have benefit to view short url for external links which when shared will record the visit count to that url.
The original url is stored in PostVideos table for all user.
I have created a table to store uniuqe keys for short urls inside short_video_post_urls with columns
+----+---------------+------------+-------------+
| id | post_video_id | unique_key | visit_count |
+----+---------------+------------+-------------+
Since, count of Pro members will be low than normal users, I don't want to generate unique_key entry in short_video_post_urls because It will flood database with useless records.
So, what I want is to generate them dynamically and store them for PRO members only
Now, in template file I'm using $postVideo->video_url to display original video url from post_videos table.
Question
What I want is to tweak video_url entity call which will check for
Membership level of logged in user
If member is pro
check if unique key exists in ShortVideoPostUrls model for the url requested
If no record exists, then create a unique_key in ShortVideoPostUrls
return the new url with unique_key
But for that I need to access logged_in user data in the entity class.
What I tried?
class PostVideoLog extends Entity
{
/*
* ----
* ----
*/
protected function _getVideoUrl()
{
$user = $this->Users->get($this->Auth->user('id'), [
'contain' => [
'MembershipLevels'
]
]);
if ($user) {
if (strtolower($user->membership_level->title) === 'pro') {
/**
* check if unique_key exists for this request
*/
$checkShortUrl = $this->ShortVideoPostUrls->find()
->where(['post_video_log_id' => $this->_properties['id']])
->first();
if ($checkShortUrl) {
return $this->_generateUrl($checkShortUrl->unique_key);
}
/**
* create new record
*/
$unique_key_generator = new Hashids(UNIQUE_SHORT_URL_SALT, 4);
$unique_key = $unique_key_generator->encode($this->_properties['id']);
$newShortUrl = $this->ShortVideoPostUrls->newEntity();
$newShortUrl = $this->ShortVideoPostUrls->patchEntity($newShortUrl, [
'unique_key' => $unique_key,
'post_video_log_id' => $this->_properties['id']
]);
if ($this->ShortVideoPostUrls->save($newShortUrl)) {
return $this->_generateUrl($unique_key);
}
}
}
return $this->_properties['video_url'];
}
private function _generateUrl($unique_key)
{
$base_url = Router::url('/', true);
return $base_url . '/u/' . $unique_key;
}
}
I'm not sure, whether my approach is right or wrong.
To load Users model and other models I'm using in above function requires to use
$this->loadModel('Users');
But, loadModel seems not to be working here.
What is other approach to do this? Or how to load external model and Auth component in Entity class?
Edit 2
Is there any better alternative to do what I want without entity? or simply some way to call function from template on each entity?
Ex.
$postVideo->video_url()
To load other model inside entity You can use TableRegistry class
use Cake\ORM\TableRegistry;
class MyModel extends Entity {
protected function _getVideoUrl() {
$table = TableRegistry::get('Users');
$users = $table->find('all')->toArray();
}
}
I think its not the best idea to use Auth component in model - I dont know how to do this "properly", but all session data (including auth data) is still available in $_SESSION array

Resources