relation function in models using laravel - php

I have 3 tables.one is user,second is event and third is eventParticipants.Here i have 3 type of users. one is organizer its status is 1,second is participant its status is 2,third is subparti which organizer and particiant can create and their status is 3.when participant register a event it stores in a eventParticipant table.Also if participant registering event by his participant it also save on the same eventParticipant table.Now my problem comes in the part of listing this registeration in participant dashboard.Here i need to list both participant and his subparti registration detail.But i cnoont get the whole data.I listed my tabel structure below:
1.user
id name email status createdBy
1 A AA 2 0
2 A1 AA1 3 1
3 A2 AA2 3 2
2.EventPArticipants
id eventid eventowner name email
25 18 A AA
27 14 A1 AA1
22 17 A2 AA2
when i am listing in the participant home.blade.php i need:
Name event date action
A Event1 04/05/2020 show
A1 Event2 04/08/2020 show
A2 Event3 04/05/2020 show
here i used model relation but i dont get subpartis.
eventPArticipants.php
public function active(){
return $this->hasMany('App\Models\EventParticipants', 'email', 'email');
}

I dont know what is eventowner, is the the user_id ??? if its the user_id then
use hasManyThrough like this
public function partis(){
return $this->hasManyThrough ('App\Models\Event',
'App\Models\EventParticipants',
'eventowner' or user_id,
'id', // Foreign key on Event table...
'id', // Local key on user table...
'id' // Local key on EventParticipants
);
}
pull the data like This in your controller
$data = User::with('partis')
->where('additional logic')
->get();
You can use callback as well... make Sure Your pivot table (EventPArticipants) is well
By this you can get exact events of the user

Related

How to get the Hierarchy recursively in laravel

I have 2 tables i.e. users and user_managers, with the following structure and data:
users
id
name
employee_number
1
Employee One
ACB1234
2
Employee Two
XYZ1234
3
Employee Three
EFG1234
4
Employee Four
HIJ1234
user_managers
id
user_id
manager_of_user_id
1
1
2
2
2
3
3
4
1
4
5
4
I want a recursive function to get the complete chain of the managers. For example, if query for user_id = 4, I should get the following result:
result
user_id
name
employee_id
comments
1
Employee One
ABC1234
user managed by 4
2
Employee Two
XYZ1234
user managed by 1
3
Employee Three
EFG1234
managd by user 2
5
Employee Five
JKL1234
manager of user 4
The table above is just for the clarification, I am looking for a recursive function to get the above result.
I have tried the below solution but it is working for only 1 level.
public static function getCompleteChain(User $user)
{
$managerUsers = $user->managers;
foreach ($managerUsers as $manager) {
$manager->user = User::where('employee_id', $manager->manager_of_user_id)->first();
self::getCompleteChain($manager->user);
}
return $managerUsers;
}
Thanks in advance.

Check if given date is available from multiple table

I am working on online reservation system where customer will search for room available with time and number of people. My database table looks like this:
Table: Property
id
property_name
property_number
1
abc property
AB-123
2
def property
DF-343
property_number is unique field
Table: Rooms
id
Room Name
Capacity
property_number
1
Room one
150
AB-123
1
Room two
500
AB-123
2
Room one
500
DF-343
property_number is foreign key from table property
Table: Booking
id
property_number
room_id
book_status
book_start
book_end
1
AB-123
1
active
2021-06-06 10:00:00
2021-06-06 18:00:00
property_number is foreign key from table property
room_d is foreign key from table Room
book_status : completed, pending, running, cancelled. If booking status is completed or cancelled than user should be able to book.
User Search Field
Reservation Date
Reservation Start Time
Reservation End Time
Total no of People
User Submits Specific Property Number
Solution Tried
$property = Property:::where('status','active')->where('property_number',$property_number)->firstOrFail();
$bookings = $property->bookings()
->whereBetween('event_date_start',[$event_start,$event_end])
->orWhereBetween('event_date_end',[$event_start,$event_end])
->orWhere( function ( $query ) use ($event_start,$event_end) {
$query->where('event_date_start' , '<', $event_start)->where('event_date_end','>',$event_end);
})
->get();
Model Structure
Table: **Property**
Class Property extends Model {
public function bookings(){
return $this->hasMany(Bookings::class,'property_number','property_number');
}
public function rooms(){
return $this->hasMany(Rooms::class,'property_number','property_number');
}
}
Table: **Rooms**
Class Rooms extends Model {
public function property(){
return $this->belongsTo(Property::class,'property_number','property_number');
}
public function bookings(){
return $this->hasMany(Bookings::class,'room_id');
}
}
Table: **Bookings**
Class Bookings extends Model {
}
This way it checks only property not every room associated with the property.
How to check if any room is available for booking for provided property.*

Adding column that displays count of record under same group gridview yii2

I am trying to count the record with the same group in a table. I know this is attainable easily with a query and yes I already done it but I am thinking of the proper way to place the count on main models and search models.
The database looks like this:
Device
----------------------------
id name group_id
1 Phone Sony 2
2 Computer 1
3 Printer 1
4 Phone LG 1
Group
----------------------------
id name
1 Home
2 Office
OUTPUT TABLE:
Group Name Device Count
Home 1
Office 3
I have done this by doing a query on the controller.
SELECT COUNT( * )
FROM `hosts`
WHERE group_id = *~DESIRED NUMBER HERE~*
I am looking for a better approach. I am new to SQL and I think joining tables is the proper way to do this but I am still not very sure.
Under GroupSearch model I will add this:
$dataProvider->setSort(['attributes' => [
'devicecount' => [
'asc' => [ 'devicecount' => SORT_ASC ],
'desc' => [ 'devicecount' => SORT_DESC ],
],
]
]);
Since devicecount is not available in the tables it will show an error. Where should I put the counting of the same store_id? Under Device model or under Group model? How will I be able to sort them also?
There is an example of handling this kind of situations in official guide.
Example of model:
class Group extends \yii\db\ActiveRecord
{
public $devicesCount;
// ...
public function getDevices()
{
return $this->hasMany(Device::className(), ['group_id' => 'id']);
}
}
Example of query:
$customers = Group::find()
->select([
'{{group}}.*', // select all customer fields
'COUNT({{device}}.id) AS ordersCount' // calculate orders count
])
->joinWith('devices') // ensure table junction
->groupBy('{{group}}.id') // group the result to ensure aggregation function works
->all();
where {{group}} and {{device}} - table names for groups and devices accordingly, or you can use Group::tableName() and Device::tableName() for better code maintaining.
Then because you added count as model property, you will be able to sort results by this column.

yii2:autofill on multiple condtions

I have models/tables as follows:
table room_category
id room_category
1 Classic
2 Deluxe
table room_charges
id room_category room_name room_charges
1 1 c1 600
2 2 d1 800
table ipd_charges
id doctor room_category charges_cash charges_cashless
1 1 1 200 300
2 1 2 300 400
table patient_detail(patient_admission)
id patient_name tpa_name(if not null, equivalent to charges_cashless)
1 1 Null
2 2 1
table daily_ward_entry
id patient_name room_name(id) doctor_name(id) charges ( from ipd_charges)
1 1 1 1 200
2 2 2 1 400
Now there is a dropdown field in daily_ward_entry table for doctor. When I select the drop-down field the charges field needs to be autofilled.
I achieve this using Jason and ajax with the following code without taking into account the room_category. but the charges vary for room_category.(this is only working after saving the record, I prefer if there is someway to pull the charges before save.)
Here is my code in the controller:
public function actionChargesCash($id){
$model = \app\models\IpdCharges::findOne(['doctor'=>$id]);
return \yii\helpers\Json::encode(['visit_charges'=>$model->charges_cash]);
}
public function actionChargesCashLess($id){
$model= \app\models\IpdCharges::findOne(['doctor'=>$id]);
return \yii\helpers\Json::encode(['visit_charges'=>$model->charges_cashless]);
}
I have also tried this variaton:
public function actionChargesCash($id){
$model = \app\models\IpdCharges::find()
->where(['doctor'=>$id])
->andwhere(['room_category'=>'daily_ward_entry.room_name'])->one();
If I replace the 'daily_ward_entry.room_name' with room_name id like 3 or 6, I am getting the result, which means I am not using the correct syntax for referring the column from current table.
How can I include the condition for room_name in the above code?
Thanks in advance for your valuable help.
daily_ward_entry.room_name is meaningless without any relation or join or sub-query. Actually, the query does not know the daily_ward_entry.
Suggestions:
1- Create a relation and use with or Join With
2- Create a query with Join of daily_ward_entry and ipd_charges on room_name=room_category
3- Create a query with a sub-query, to find all|one IpdCharge(s) that have room_category in SELECT room_name FROM daily_ward_entry
All of above suggestions satisfy your requirements.
Another important note:
andWhere()/orWhere() are to apply where to the default condition.
where() is to ignore the default condition
I don't see any default condition (Overridden Find()), So, there is no need to use andWhere, Just:
where(['doctor'=>$id,'room_category'=>3,...])
Would be sufficient.

Avoiding duplicates Database records in a datamapper code igniter

My Question is simply how to insert data into the join table(user_book) without inserting a duplicate entry into the main table(book).
Mainly consider we have tree table below
id Users id Books id Users Books
1 Sam 1 B1 1 1 1
2 Ben 2 B2 2 1 3
3 Mike 3 B3 3 3 3
4 2 2
But the problem is when I am inserting a new book(ex Mike like B3) that exist in the Books table. The duplicate will appear in the books table and the above table will be like:
id Users id Books id Users Books
1 Sam 1 B1 1 1 1
2 Ben 2 B2 2 1 3
3 Mike 3 B3 3 3 4
4 B3 4 2 2
Is that make sense now what I am trying to resolve? Or maybe I can't have a unique list of books at all?
if I am going to insert
Given the database
users and books
users<--->books are related by users_books
we need to make sure that when we insert a book record to the db it is not a duplicate. Further, if the book exist, a relation will be inserted and not the book record . How can one do that?
One approach is to say
$m=new Book();
$m->where('id_book', $data['user_booklist'][$i]['id'])->get();
$u = new User();
$u -> where('id_user', $data['user_profile']['id'])-> get();
if(!$u->where_related($m))
{
$m -> name = $data['user_booklist'][$i]['name'];
$m -> id_book = $data['user_booklist'][$i]['id'];
$m -> save($u);
}
if (book->exist) in the "books" table
then check the relation and see if there is a relationship between users and books and if there is then don't insert it. Further do I need to change any thing in the mysql db structure to avoid this.
The above code is not working but should give an idea what I am talking about.
Update:
In summary, if two users liked the same book, I just want to insert a record(book) into the join table (users_books) and while not to creating a new record in the table. Using the unique sql tag did not work since it keeps unique list but it prevents from inserting the multiple relationships into the join table users_books.
You could do:
$b = new book();
$b->where('id_book', $data['user_booklist'][$i]['id'])->get();
// I believe you can do this as well, but I'm not sure:
// $b->where('id', $data['user_booklist'][$i]['id'])->get();
$u = new user();
$u -> where('id_user', $data['user_profile']['id'])-> get();
if( $b->exists() && $u->exists() )
{
// This saves the relationship between the book and the user
$b->save($u);
}
else
{
// Could not find the book or the user
}
You should check out the datamapper-manual on saving relationships.

Categories