Pivot table but not using table id - laravel

Is it possible to make a Pivot Table without using table id?
users
id
biometric_id
first_name
last_name
attendances
id
biometric_id
date
emp_in
emp_out
user_attendances
user_id
attendances_biometrics_id
I wanted to ask if this is available to link it like this? Because I need to show the attendance of the user that has his biometrics.
If it is possible, how?

If attendances.biometric_id has a unique constraint on it then there should be no reason why you cannot use it as a foreign key constraint.
Assuming your tables have been setup properly with foreign key constraints, your user model would probably have something like this:
public function attendances() {
return $this->belongsToMany('App\Attendances', 'user_attendances', 'user_id', 'attendances_biometrics_id');
}

Related

How to access to user data through intermediate table (hasOneThrough / hasManyThrough)

For a job posting application, I have three tables, which shortly are defined as:
applications:
id as primary key
job_offer_uuid as external key
job_offers:
uuid as primary key
user_id as external key
users:
Just laravel normal users table with id as primary key
Because I need to notify job_offer owner (a member of User model) any time that an application is registered, I'm trying to create a hasOneThrough or hasManyThrough relationship from applications to users, but without success for the moment.
For clarification:
User model only hosts users that publish job offers, and any user can publish many job offers. There is not applicants in users table
Based on my understanding of eloquent documentation (https://laravel.com/docs/8.x/eloquent-relationships#has-one-through), my actual code in Application model is:
public function publisher()
{
return $this->hasOneThrough(User::class, JobOffer::class, 'job_offer_uuid', 'user_id');
}
But it fires an SQL error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_offers.job_offer_uuid' in 'field list' (SQL: select `users`.*, `job_offers`.`job_offer_uuid` as `laravel_through_key` from `users` inner join `job_offers` on `job_offers`.`id` = `users`.`user_id` where `job_offers`.`job_offer_uuid` in (1)
using hasManyThrough instead, I got an identical error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_offers.job_offer_uuid' in 'field list' (SQL: select `users`.*, `job_offers`.`job_offer_uuid` as `laravel_through_key` from `users` inner join `job_offers` on `job_offers`.`id` = `users`.`user_id` where `job_offers`.`job_offer_uuid` in (1))
I can get accurate results using pure SQL with a sentence like this:
select applications.id, applications.job_offer_uuid, job_offers.uuid, job_offers.user_id, users.id, users.name, users.email from `applications` inner join job_offers on `applications`.`job_offer_uuid` = `job_offers`.`uuid` join users on job_offers.user_id = users.id where `applications`.id = 1
Any video or tutorial that I found related to this point are using the final table with a foreign key to the intermediate table, and thats means my User model should have a foreign job_offer_id key, but that make no sense to me.
Any clarification should be truly appreciate. Regards!
You are doing it wrong. You have to define relationship in User Model as follow:
public function publisher()
{
return $this->hasOneThrough(
Application::class,
JobOffer::class,
'user_id', // Foreign key on job_offers table
'job_offer_uuid', // Foreign key on applications table
'id', // Local key on user table
'uuid' // Local key on job_offer table
);
}

Create table as select statement primary key in oracle

Is it possible to specify which is the primary key on creating table as select statement? My aim is to include the declaration of primary key on the create table not modifying the table after the creation.
CREATE TABLE suppliers
AS (SELECT company_id, address, city, state, zip
FROM companies
WHERE company_id < 5000);
Yes, it's possible. You would need to specify columns explicitly:
CREATE TABLE suppliers (
company_id primary key,
address,
city,
state,
zip
)
AS
SELECT company_id, address, city, state, zip
FROM companies
WHERE company_id < 5000;
Here is a demo
Note: in this case primary key constraint will be given a system-generated name. If you want it to have a custom name you'd have to execute alter table suppliers add constraint <<custom constraint name>> primary key(<<primary_key_column_name>>) after executing(without primary key specified) CREATE TABLE suppliers.. DDL statement.
Yes, it's possible.You can try referring below example.
create table student (rollno ,student_name,score , constraint pk_student primary key(rollno,student_name))
as
select empno,ename,sal
from emp;
You can create Suppliers table explicitly and if any column have primary key in companies table, then copy that structure from companies table.
Or
Create a same column defining primary key that you want and copy that column from companies table!

Laravel / Eloquent -- Lookup Table Issue

I have 3 tables that I am trying to work through and am having a hard time connecting them via Eloquent joins.
Character Table
profileID (PK)
Character Gear Table
profileId (PK)
qualityId (FK)
Quality Lookup Table
id (PK)
name
I am able to access the Character Gear Lookup with the following in my Character Model:
public function gear()
{
return $this->hasMany('App\Models\CharacterGear', 'profileId')->where('gearSet', '=', '0');
}
How do I get the lookup to work so that I can get the quality name from the Quality Lookup table to tie in to the gear() shown above?
Please let me know if you need any further information!
Figured it out. Eloquent has Nested Relationships and I didn't know that.

Relation belongs to table with double primary key in Laravel

I need to store in a database the weekly hour of an user. For example, the user A work at monday from 8:00am to 17:00pm, on tuesday from 9:00am to 11:00am ecc...
For do this I created two table:
Users (id, username, ecc...)
Hours (user_id, day, start, end) with "user_id" and "day" as primary key.
Instead of create another table called Days with only 7 records (one for each day).
My problem is to define the relation with laravel, indeed if I use three tables I can use Many to Many relation, but if I use this form how I can specific that "day" column is a key?
I suggest following table structure of Hours
id (primary key, auto-increment)
user_id
day (NOT primary key, values from 1-7)
start
end
Then you can add a UNIQUE index over the combination of user_id and day.
SQL: ALTER TABLE hours ADD UNIQUE unique_user_day (user_id, day);
Laravel schema builder (migration): $table->unique(array('user_id', 'day'));
After that you just need a normal relation. Nothing fancy at all.
public function hours(){
return $this->hasMany('Hours');
}
This is how you get all hours
$hours = Users::find(1)->hours;
And then, when you need a specific day, add a where statement
$tuesday = Users::find(1)->hours()->where('day', 2)->get();
Or for a nicer syntax you could a function to your users model
public function day($number){
return $this->hours()->where('day', $number)->get();
}
$tuesday = Users::find(1)->day(2);
You could even work with constants for the weekdays...

Soft delete on a intermediate table for many-to-many relationship

How do I set soft delete on an intermediate table which is connecting two different types of entities? I've added deleted_at column, but the docs say that I need to put this into the model:
protected $softDelete = true;
Of course, I don't have a model for an intermediate table.
Any idea?
You can put a constraint on the Eager Load:
public function groups()
{
return $this
->belongsToMany('Group')
->whereNull('group_user.deleted_at') // Table `group_user` has column `deleted_at`
->withTimestamps(); // Table `group_user` has columns: `created_at`, `updated_at`
}
Instead of HARD deleting the relationship using:
User::find(1)->groups()->detach();
You should use something like this to SOFT delete instead:
DB::table('group_user')
->where('user_id', $user_id)
->where('group_id', $group_id)
->update(array('deleted_at' => DB::raw('NOW()')));
You could also use Laravel's Eloquent BelongsToMany method updateExistingPivot.
$model->relation->updateExistingPivot($relatedId, ['deleted_at' => Carbon\Carbon::now()]);
So to use #RonaldHulshof examples you have a User model with a groups relationship which is a belongsToMany relationship.
public function groups() {
return $this->belongsToMany(Group::class)->whereNull('groups_users.deleted_at')->withTimestamps();
}
Then in order to soft delete the pivot table entry you would do the following.
$user->groups()->updateExistingPivot($groupId, ['deleted_at' => Carbon\Carbon::now()]);
As far as I understand it; an intermediate table is simply a length of string attaching one tables record to a record in another table and as such it does not require a soft delete method.
To explain, imagine you have a Users table and a Groups table, each user can have more than one Group and each Group can belong to more than one User. Your pivot table may be User_Group or something like that and it simply contains two columns user_id and group_id.
Your User table and Group table should have a deleted_at column for soft deletes, so when you "delete" say a Group, that group association will not appear in $User->Groups() while the pivot table row has remained unaffected. If you then restore that deleted Group, it will once again appear in $User->Groups().
The pivot table row should only be affected if that group record is hard deleted, in which case the pivot rows should also be hard deleted.
Now I have explained why I do not believe you need to add soft delete to a pivot table; is there still a reason why you need this behavior?

Resources