I'm trying to make a role based access control system, but the problem comes when I approach the Database Part of It.
Should I make two models, Role and Permission, and then make a many to many relationship between role and permission or what?
My User Model looks something like this:
Column | Type | Collation | Nullable | Default
------------+-----------------------------+-----------+----------+--------------------
id | uuid | | not null | uuid_generate_v4()
name | character varying(50) | | not null |
email | character varying(320) | | not null |
avatar | text | | |
password | text | | not null |
phone | character varying(30) | | |
created_at | timestamp without time zone | | not null | now()
updated_at | timestamp without time zone | | | now()
companyId | uuid | | |
roleId | uuid | | |
So I just have 1 to many relation ship between user and role.
Mainly it's done with a single role and multiple users associated with it.
Roles can be assigned privileges and users can be assigned roles.
You can refer following for the same.
Role-based access control in Postgres/mongo
Related
I have SQL for example
show tables from mydb;
It shows the list of table
|table1|
|table2|
|table3|
Then,I use sql sentence for each table.
such as "show full columns from table1 ;"
+----------+--------+-----------+------+-----+---------+----------------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+----------+--------+-----------+------+-----+---------+----------------+---------------------------------+---------+
| id | bigint | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
| user_id | bigint | NULL | NO | MUL | NULL | | select,insert,update,references | |
| group_id | int | NULL | NO | MUL | NULL | | select,insert,update,references | |
+----------+--------+-----------+------+-----+---------+----------------+---------------------------------+---------+
So in this case I can use programming language such as .(this is not correct code just showing the flow)
tables = "show tables from mydb;"
for t in tables:
cmd.execute("show full columns from {t} ;")
However is it possible to do this in sql only?
If you are using MySQL you can use the system view - INFORMATION_SCHEMA.
It contains table name and column name (and other details). No loop is require and you can easily filter by other information, too.
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
If you are using Microsoft SQL Server, you can use the above command
I am currently trying to optimize some workflows here. One of our workflows involves calculating a time offset in hours from a given date, and that involves selecting from a number of tables and applying some business logic. That part of the problem is fairly well solved. What I am trying to do is to calculate a final timestamp based upon a timestamp value and an offset (in hours).
My source table looks like:
MariaDB [ingest]> describe tmp_file_3;
+---------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------------+------+-----+---------+-------+
| mci_idx | bigint(20) unsigned | YES | | NULL | |
| mcg_idx | bigint(20) unsigned | YES | | NULL | |
| ingested_time | timestamp | YES | | NULL | |
| hours_persist | int(11) | YES | | NULL | |
| active | tinyint(1) | YES | | NULL | |
+---------------+---------------------+------+-----+---------+-------+```
And I am populating my new table with the following SQL:
MariaDB [ingest]> insert into master_expiration_index (select mci_idx, TIMESTAMPADD(HOUR, hours_persist, ingested_time) as expiration_time from tmp_file_3 where active=1);
ERROR 1292 (22007): Incorrect datetime value: '2023-03-12 02:20:15' for column `ingest`.`master_expiration_index`.`expiration_time` at row 347025
The SQL is correct to my understanding, since if I add a limit 10 to the query executes without any issues. The questions I have are:
What is wrong with that datetime value? It appears to be in the correct format
How do I figure out which row is causing the issue?
How do I fix this in the general case?
this is more of a SQL question than a PostGIS question, but I'm getting stuck again :(
I have a table called referred with id numbers in the "from" and "to" columns.
I want to calculate the distance between ALL these id numbers based on their zip code.
There is a separate reference table called doc which contains the id number in column "NPI" and zip code in column "Provider Business Mailing Address Postal Code" and a separate geo table called zctas which has zip code column as zcta and geom column.
For example, this query works fine:
SELECT z.zcta As zip1,
z2.zcta As zip2,
ST_Distance(z.geom,z2.geom) As thedistance
FROM zctas z,
zctas z2
WHERE z2.zcta = '60611'
AND z.zcta='19611';
One catch is that the "Provider Business Mailing Address Postal Code" should = left("Provider Business Mailing Address Postal Code", 5).
I'm getting stuck on JOIN-ing the 2 zip codes from the reference table in this one query.
Sample table:
referred table:
from | to | count
------------+------------+-------
1174589766 | 1538109665 | 108
1285653204 | 1982604013 | 31
desired output:
from | to | count | distance
------------+------------+----------------
1174589766 | 1538109665 | 108 | 53434
1285653204 | 1982604013 | 31 | 34234
\d+
Table "public.zctas"
Column | Type | Modifiers | Storage | Stats target | Description
------------------+------------------------+-----------+----------+--------------+-------------
state | character(2) | | extended | |
zcta | character(5) | | extended | |
junk | character varying(100) | | extended | |
population_tot | bigint | | plain | |
housing_tot | bigint | | plain | |
water_area_meter | double precision | | plain | |
land_area_meter | double precision | | plain | |
water_area_mile | double precision | | plain | |
land_area_mile | double precision | | plain | |
latitude | double precision | | plain | |
longitude | double precision | | plain | |
thepoint_lonlat | geometry(Point,4269) | | main | |
thepoint_meter | geometry(Point,32661) | not null | main | |
geom | geometry(Point,32661) | | main | |
Indexes:
"idx_zctas_thepoint_lonlat" gist (thepoint_lonlat)
"idx_zctas_thepoint_meter" gist (thepoint_meter) CLUSTER
Table "public.referred"
Column | Type | Modifiers | Storage | Stats target | Description
--------+-----------------------+-----------+----------+--------------+-------------
from | character varying(25) | | extended | |
to | character varying(25) | | extended | |
count | integer | | plain | |
Has OIDs: no
Table "public.doc"
Column | Type | Modifiers | Storage | Stats target | Description
--------------------------------------------------------------+------------------------+-----------+----------+--------------+-------------
NPI | character varying(255) | | extended | |
Entity Type Code | character varying(255) | | extended | |
Replacement NPI | character varying(255) | | extended | |
Employer Identification Number (EIN) | character varying(255) | | extended | |
Provider Organization Name (Legal Business Name) | character varying(255) | | extended | |
Provider Last Name (Legal Name) | character varying(255) | | extended | |
Provider First Name | character varying(255) | | extended | |
Provider Middle Name | character varying(255) | | extended | |
Provider Name Prefix Text | character varying(255) | | extended | |
Provider Name Suffix Text | character varying(255) | | extended | |
Provider Credential Text | character varying(255) | | extended | |
Provider Other Organization Name | character varying(255) | | extended | |
Provider Other Organization Name Type Code | character varying(255) | | extended | |
Provider Other Last Name | character varying(255) | | extended | |
Provider Other First Name | character varying(255) | | extended | |
Provider Other Middle Name | character varying(255) | | extended | |
Provider Other Name Prefix Text | character varying(255) | | extended | |
Provider Other Name Suffix Text | character varying(255) | | extended | |
Provider Other Credential Text | character varying(255) | | extended | |
Provider Other Last Name Type Code | character varying(255) | | extended | |
g(255) | | extended | |
Provider Second Line Business Mailing Address | character varying(255) | | extended | |
Provider Business Mailing Address City Name | character varying(255) | | extended | |
Provider Business Mailing Address State Name | character varying(255) | | extended | |
Provider Business Mailing Address Postal Code | character varying(255) | | extended | . . . . other columns not really needed.
Thanks!!!!
This should be relatively straightforward.
Assuming the NPIs are actually all the same length in doc and referred, you can join those tables quite easily:
SELECT ad."Provider Business Mailing Address Postal Code" as a_zip,
bd."Provider Business Mailing Address Postal Code" as b_zip,
r."count"
FROM referred r
LEFT JOIN doc ad ON r."from" = ad."NPI"
LEFT JOIN doc bd ON r."from" = bd."NPI";
Obviously, adjust this join based on careful analysis of the NPI and from/to fields in your data. Add trim or left method calls within the join if necessary -- the most important thing is that the JOIN condition be on comparable data.
Now, going from this to your original query to find a distance is trivial:
SELECT ad."Provider Business Mailing Address Postal Code" as a_zip,
bd."Provider Business Mailing Address Postal Code" as b_zip,
r."count",
ST_Distance(az.geom,bz.geom) As thedistance
FROM referred r
LEFT JOIN doc ad ON r."from" = ad."NPI"
LEFT JOIN doc bd ON r."from" = bd."NPI"
LEFT JOIN zctas az
ON az.zcta = left(ad."Provider Business Mailing Address Postal Code",5)
LEFT JOIN zctas bz
ON bz.zcta = left(bd."Provider Business Mailing Address Postal Code",5)
This is just one construction that should work, many others are possible. This particular construction will ensure that every entry in referred is represented, even if the NPI doesn't match to an entry in the doc table, or a zipcode can't be matched against the zctas table.
On the flip side, if there exists more than one entry for an NPI in the doc table, any referred entry that mentions this duplicated NPI will also be duplicated.
Similarly, if there is more than one entry in zctas for a particular zip code (zcta), you would see duplicates of referred rows.
That's how LEFT JOIN works, but I figured it was worth putting in the warning, as Provider data is typically full of duplicates against NPI, and there are often duplicate zip codes in zip code lookup lists as some zip codes cross state lines.
I'm with a great difficulty in formulate a SQL for a module of notifications when a new user register.
I have a database of Notifications, I set up a notification to be sent. Examples:
Send notification when a man and blue eyes register;
Send notification when a woman register;
Send a notification when a blue-eyed woman, brown and work in the company Foo;
With these rules we can see that there can be several possibilities (so the table columns are optional).
Some details:
The table columns are defined as integers because are FK. I just did not put tables because the structure is unnecessary, since the SQL will only relashionship between User and Notification;
The date field is used to store both the date of registration of the notice of such person. So I can only filter to notify the new register of user;
Table Structure
User:
+------------+----------+------+-----+---------+------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+------------+
| Id | int(11) | NO | PRI | | auto_incre |
| Gender | int(11) | YES | | | |
| HairColor | int(11) | YES | | | |
| EyeColor | int(11) | YES | | | |
| Company | int(11) | YES | | | |
| Date | datetime | NO | | | |
| ... | | | | | |
+------------+----------+------+-----+---------+------------+
Notification:
+------------+----------+------+-----+---------+------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+------------+
| Id | int(11) | NO | PRI | | auto_incre |
| Gender | int(11) | YES | | | |
| HairColor | int(11) | YES | | | |
| EyeColor | int(11) | YES | | | |
| Company | int(11) | YES | | | |
| Date | datetime | NO | | | |
+------------+----------+------+-----+---------+------------+
Initial idea
The initial idea I had was doing a select for each possibility and joining via union:
-- Selects new users by gender notification
SELECT *
FROM Notification
inner join User on (
User.Date >= Notification.Date and
Notification.Gender = User.Gender and
Notification.HairColor is null and
Notification.EyeColor is null and
Notification.Company is null
)
union all
-- Selects new users by gender and hair color notification
SELECT *
FROM Notification
inner join User on (
User.Date >= Notification.Date and
Notification.Gender = User.Gender and
Notification.HairColor = User.HairColor and
Notification.EyeColor is null and
Notification.Company is null
)
-- ... and so on, doing a select for each option, resulting in 16 selects (4 columns: gender, hair color, eye color and company)
My question is:
Is there another way I can do this SQL querying all the possibilities of notifications in a more easy?
Following this structure of 4 columns we already have 16 selects. In my real structure will have more columns with something unfeasible to keep it that way.
Is there any other suggestion storage structure of the data for a better way to do this functionality?
SELECT *
FROM Notification
inner join User on (
User.Date >= Notification.Date and
(Notification.Gender is null or Notification.Gender = User.Gender) and
(Notification.HairColor is null or Notification.HairColor = User.HairColor) and
(Notification.EyeColor is null Notification.EyeColor = User.EyeColor) and
(Notification.Company is null or Notification.Company = User.Company)
)
This way you get every set of user with the notification stored in the tables.
This is the way I would implement this user registration / notification functionality:
Three tables: Users, Notif_type, Notif_queue.
A trigger on insert on table Users which calls a stored procedure SendNotification(user_id).
The stored proc will have the logic which you can change overtime without having to modify the schema/data. The logic will be:
to select the type of notification (form Notif_type) the new user should receive based on your rules;
to insert a row in Notif_queue which holds a FK to user_id and notif_type_id, so that the functionality notifying the user is completely de-coupled from the notification rules.
why can't you just use the one table "user" and put an extra field/flag called [Notified] so that every time you want to send notifications just refer it to the flag.
i find it irrelevant to use the notification table.
I want to give an option in my application to let the use choose maximum 3 custom fields of his choice, how is it possible ? I know their is some easy solution for this but can't get that.
I mean is it possible in rails to let the user select the label for extra fields he wants in his data. FOr example i have a table fruit with fields name, type, taste and two extra fields extra_field1 and extra_field2. The first 3 fields are visible on the form with same label and a link to add custom fields, after clicking on that link user gets a form where he can label the extra fields of his choice like person A name them rate and weight while person B name them rate and color etc. After the name setting the extra field should be visible to user on the form every time he creates a new record.
One solution can be that you can have model CustomField, set available custom fields in custom_fields table. Use multi select dropdown to allow user to select custom fields, as many as he want.
And there will be an intermediate model which will have user_id, 'custom_fields_id' and value.
Your associations might be like this.
user.rb
has_many :custom_fields, :through => 'UserCustomFields'
user_custom_field.rb
belongs_to :user
belongs_to :custom_field
custom_field.rb
has_many :users, :through => 'UserCustomFields'
I have added a new table to database with name "custome_field" that contains the followitn columns:
mysql> desc custom_fields;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| company_id | int(11) | NO | | NULL | |
| voucher_type | varchar(255) | NO | | NULL | |
| custom_label1 | varchar(255) | YES | | NULL | |
| custom_label2 | varchar(255) | YES | | NULL | |
| custom_label3 | varchar(255) | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
And added three new column to my table a as custom_field1, custom_field2 and custom_field3.
Now i can set label in custom_field table and class for which i want the custom fields and use them in form i need.
Thanks to #Ramiz Raja for supporting me on this.