સુપાબેસ, રિએક્ટ, એસ્ટ્રો, અને ક્લાઉડફ્લેર સાથે એક સ્લીક બ્લોગ બનાવવું – ભાગ 2: નીતિઓ, ફંક્શન્સ, અને ટ્રિગરો સાથે તમારા ડેટાબેઝને ફાઈન-ટ્યૂનિંગ કરવું

/* by Tirth Bodawala - August 17, 2024 */

Welcome back! Now that we’ve got our UserProfile and Posts tables set up, it’s time to add some serious firepower to our backend. In this part, we’re going to explore how to use functions, triggers, and Row-Level Security (RLS) policies in Supabase to automate tasks, secure your data, and ensure your blog runs like a well-oiled machine. Let’s jump in and make your blog backend as smart and secure as possible!

ટેબલ ઓફ કન્ટેન્ટ્સ

  1. ફંક્શન્સ અને ટ્રિગરો સાથે ઑટોમેટિંગ
    • URL-ફ્રેન્ડલી સ્લગ્સ જનરેટ કરવું
    • અનન્ય પોસ્ટ ID બનાવવી
    • ઓટોમેટિકલી લેખકો નિમણૂક કરવી
    • ટાઈમસ્ટેમ્પ્સ અને સોફ્ટ ડિલીટ્સ મેનેજ કરવું
  2. ટેબલ દ્વારા સુરક્ષિત કરવું તમારા ડેટાને રો-લેવલ સુરક્ષા (RLS) નીતિઓ સાથે
    • RLS સક્રિય કરવું
    • નીતિઓ બનાવવી
    • કોઈ પણ ઓથેન્ટિકેટેડ વપરાશકર્તાને પોસ્ટ્સ દાખલ કરવાની અનુમતિ આપવી
    • પોસ્ટ્સને અપડેટ અને ડિલીટ કરવું—ફક્ત લેખક દ્વારા
    • પ્રકાશિત સામગ્રીને ઍક્સેસ નિયંત્રિત કરવું
  3. અનન્ય ID ના અપડેટને અટકાવવું
    • અનન્ય ID ના અપડેટને અટકાવવું
    • અનન્ય ID ચેક લાગુ કરવું
  4. વપરાશકર્તા પ્રોફાઇલ્સમાં ઇમેઇલની સુસંગતતા સુનિશ્ચિત કરવી
    • વપરાશકર્તા ની ઇમેઇલની નકલ કરવી
    • ઇમેઇલ નકલ ફંક્શન લાગુ કરવું
  5. ઇન્ડેક્સ સાથે તમારા ડેટાબેઝને ઓપ્ટિમાઇઝ કરવું

1. ફંક્શન્સ અને ટ્રિગરો સાથે ઑટોમેટિંગ

મેન્યુઅલી કંઈક કરવાની જરૂર કેમ, જ્યારે તમે તેને ઑટોમેટ કરી શકો છો? આ વિભાગમાં, અમે SQL ફંક્શન્સ અને ટ્રિગરો બનાવશું જેથી પુનરાવૃત કાર્ય જેમ કે સ્લગ્સ જનરેટ કરવું, અનન્ય ID બનાવવું, અને ટાઈમસ્ટેમ્પ્સ મેનેજ કરવું સંભાળવામાં આવે.

URL-ફ્રેન્ડલી સ્લગ્સ જનરેટ કરવું

પ્રત્યેક પોસ્ટને સ્વચ્છ, SEO-મૈત્રીપૂર્વક URLની જરૂર છે. સ્લગ્સને મેન્યુઅલી જનરેટ કરવા માટે, ચાલો એક ફંક્શન બનાવીએ જે તે અમારી માટે કરે છે:

-- Enable the unaccent extension (run this once in your database)
CREATE EXTENSION IF NOT EXISTS unaccent;

-- Function to generate a URL-friendly slug from a title
CREATE OR REPLACE FUNCTION generate_slug(title text)
RETURNS text AS $$
DECLARE
    slug text;
BEGIN
    -- Convert title to lower case, remove accents, special characters, and replace spaces with hyphens
    slug := regexp_replace(lower(unaccent(title)), '[^a-z0-9]+', '-', 'g');
    -- Remove leading and trailing hyphens
    slug := trim('-' FROM slug);
    RETURN slug;
END;
$$ LANGUAGE plpgsql;

આ ફંક્શન કોઈ પણ શિર્ષકને URL માટે સંપૂર્ણ સ્લગમાં ફેરવે છે.

ટ્રિગર સાથે ઓટોમેટિકલી સ્લગ સેટ કરવું

અમે પોસ્ટ દાખલ કરતી વખતે અથવા અપડેટ કરતી વખતે સ્લગ જનરેટ કરવાનું ભૂલવું નથી જોઈએ, તેથી ચાલો તેને ટ્રિગર સાથે ઑટોમેટ કરીએ:

CREATE OR REPLACE FUNCTION set_slug()
RETURNS TRIGGER AS $$
BEGIN
    -- Generate the slug only if it hasn't been provided or if the title changes
    IF NEW.slug IS NULL OR NEW.title IS DISTINCT FROM OLD.title THEN
        NEW.slug := generate_slug(NEW.title);
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER before_insert_update_set_slug
BEFORE INSERT OR UPDATE ON Posts
FOR EACH ROW
EXECUTE FUNCTION set_slug();

હવે, દરેક વખત તમે પોસ્ટ દાખલ કરો છો અથવા અપડેટ કરો છો, સ્લગ આપમેળે જનરેટ થાય છે.

અનન્ય પોસ્ટ ID બનાવવી

Let’s make sure every post has a unique identifier. This function generates a 10-character random string for the unique_id field:

CREATE OR REPLACE FUNCTION generate_unique_id()
RETURNS text AS $$
DECLARE
    new_unique_id text;
    exists boolean;
BEGIN
    LOOP
        -- Generate a random string of 10 characters
        new_unique_id := substr(md5(random()::text), 1, 10);
        
        -- Check if this unique_id already exists in the Posts table
        SELECT EXISTS (SELECT 1 FROM Posts WHERE unique_id = new_unique_id) INTO exists;
        
        -- Exit the loop if the unique_id does not exist
        EXIT WHEN NOT exists;
    END LOOP;
    
    RETURN new_unique_id;
END;
$$ LANGUAGE plpgsql;

સ્વચાલિત રીતે અનન્ય ID સેટ કરવી અને લેખકો નિમણૂક કરવી

We’ll use another trigger to set the unique_id and assign the author based on the current authenticated user:

CREATE OR REPLACE FUNCTION set_unique_id_on_insert()
RETURNS TRIGGER AS $$
BEGIN
    -- Generate the unique_id only if it is NULL (on insert)
    IF NEW.unique_id IS NULL THEN
        NEW.unique_id := generate_unique_id();
    END IF;
    
    -- Automatically assign the current user as the author
    IF NEW.author IS NULL THEN
        NEW.author := auth.uid();
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER before_insert_set_unique_id
BEFORE INSERT ON Posts
FOR EACH ROW
EXECUTE FUNCTION set_unique_id_on_insert();

ટાઈમસ્ટેમ્પ્સ અને સોફ્ટ ડિલીટ્સ મેનેજ કરવું

તમારા ટાઈમસ્ટેમ્પ્સને સચોટ રાખો અને સોફ્ટ ડિલીટ્સ (જ્યાં રેકોર્ડને મૃદુલી વિકલ્પ તરીકે માર્ક કરવામાં આવે છે પરંતુ વાસ્તવમાં દૂર કરવામાં આવતું નથી) સંભાળવા માટે આ ફંક્શન્સ અને ટ્રિગરોનો ઉપયોગ કરો:

Automatically Update the updated_at Field:

CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now(); -- Sets the updated_at field to the current timestamp
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER update_posts_updated_at
BEFORE UPDATE ON Posts
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();

Handle Soft Deletes by Setting the deleted_at Field:

CREATE OR REPLACE FUNCTION soft_delete_post()
RETURNS TRIGGER AS $$
BEGIN
  NEW.deleted_at = now(); -- Sets the deleted_at field to the current timestamp
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER set_deleted_at
BEFORE DELETE ON Posts
FOR EACH ROW
EXECUTE FUNCTION soft_delete_post();

2. રો-લેવલ સુરક્ષા (RLS) નીતિઓ સાથે તમારા ડેટાને સુરક્ષિત કરવું

હવે, તમારું ડેટા રો-લેવલ સુરક્ષા (RLS) સાથે સુરક્ષિત કરવું સુનિશ્ચિત કરીએ. અહીં અમે નિયંત્રણ કરીએ છીએ કે કોણ પોસ્ટ્સ દાખલ કરી શકે, અપડેટ કરી શકે, ડિલીટ કરી શકે, અથવા જુઓ.

RLS સક્રિય કરવું

પ્રથમ, અમને અમારી ટેબલ્સ પર RLS સક્રિય કરવાની જરૂર છે:

ALTER TABLE UserProfile ENABLE ROW LEVEL SECURITY;
ALTER TABLE Posts ENABLE ROW LEVEL SECURITY;

નીતિઓ બનાવવી

Let’s create a policy that ensures UserProfile data is only accessible when an email filter is applied:

CREATE POLICY allow_selecting_user_profile ON UserProfile
FOR SELECT
USING (
    true
);

This policy allows users to query UserProfile records

કોઈ પણ ઓથેન્ટિકેટેડ વપરાશકર્તાને પોસ્ટ્સ દાખલ કરવાની અનુમતિ આપવી

CREATE POLICY insert_any_authenticated_user ON Posts
FOR INSERT
WITH CHECK (auth.uid() IS NOT NULL);

આ નીતિ ખાતરી કરે છે કે ફક્ત ઓથેન્ટિકેટેડ વપરાશકર્તાઓ નવી પોસ્ટ્સ બનાવી શકે છે.

પોસ્ટ્સને અપડેટ અને ડિલીટ કરવું—ફક્ત લેખક દ્વારા

અમે અમલમાં લાવશું કે ફક્ત પોસ્ટનો લેખક તેને અપડેટ અથવા ડિલીટ કરી શકે છે:

CREATE POLICY update_own_posts ON Posts
FOR UPDATE
USING (auth.uid() = author);

CREATE POLICY delete_own_posts ON Posts
FOR DELETE
USING (auth.uid() = author);

પ્રકાશિત સામગ્રીને ઍક્સેસ નિયંત્રિત કરવું

અંતે, અમે ખાતરી કરવી છે કે ફક્ત પ્રકાશિત પોસ્ટ્સ જ જાહેર માટે દૃશ્યમાન છે, જ્યારે ઓથેન્ટિકેટેડ વપરાશકર્તાઓ બધું જોઈ શકે છે:

CREATE POLICY select_published_posts ON Posts
FOR SELECT
USING (
    auth.role() = 'authenticated' OR current_date >= publish_date
);

આ નીતિ કોઈ પણને પ્રકાશિત પોસ્ટ્સ જોવામાં અનુમતિ આપે છે, પરંતુ ફક્ત ઓથેન્ટિકેટેડ વપરાશકર્તાઓને ડ્રાફ્ટ્સ અથવા શેડ્યૂલ કરેલી પોસ્ટ્સ જોવા મળે છે.

3. અનન્ય ID ના અપડેટને અટકાવવું

Once a post is created, its unique_id should never change. To enforce this, we’ll create a function that raises an exception if someone tries to update the unique_id and a trigger to apply this function before any update operation.

ફંક્શન: અનન્ય ID ના અપડેટને અટકાવવું

Here’s the function that checks whether the unique_id is being altered:

CREATE OR REPLACE FUNCTION prevent_unique_id_update()
RETURNS TRIGGER AS $$
BEGIN
    -- Prevent the unique_id from being updated after creation
    IF NEW.unique_id IS DISTINCT FROM OLD.unique_id THEN
        RAISE EXCEPTION 'Unique ID cannot be updated';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

ટ્રિગર: અનન્ય ID ચેક લાગુ કરવું

Now, let’s attach this function to the Posts table using a trigger:

CREATE TRIGGER before_update_prevent_unique_id_change
BEFORE UPDATE ON Posts
FOR EACH ROW
EXECUTE FUNCTION prevent_unique_id_update();

With this in place, any attempt to modify the unique_id will be blocked, ensuring the integrity of your posts.

4. વપરાશકર્તા પ્રોફાઇલ્સમાં ઇમેઇલની સુસંગતતા સુનિશ્ચિત કરવી

When a new user profile is created, we want to automatically copy their email from the auth.users table to the UserProfile table. Let’s create a function and trigger to handle this.

ફંક્શન: વપરાશકર્તા ની ઇમેઇલની નકલ કરવી

CREATE OR REPLACE FUNCTION set_user_email()
RETURNS TRIGGER AS $$
BEGIN
    -- Set the email field based on the user_id from auth.users
    SELECT email INTO NEW.email FROM auth.users WHERE id = NEW.user_id;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

ટ્રિગર: ઇમેઇલ નકલ ફંક્શન લાગુ કરવું

CREATE TRIGGER before_insert_set_email
BEFORE INSERT ON UserProfile
FOR EACH ROW
EXECUTE FUNCTION set_user_email();

With this setup, every time a new UserProfile is created, the user’s email is automatically populated from the auth.users table, ensuring consistency across your data.

5. ઇન્ડેક્સ સાથે તમારા ડેટાબેઝને ઓપ્ટિમાઇઝ કરવું

To keep everything running fast, let’s optimize the slug field with an index:

CREATE INDEX idx_slug ON Posts(slug);

આ ઇન્ડેક્સ સ્લગ દ્વારા પોસ્ટ્સ માટે શોધ કરતી ક્વેરીઝને ઝડપે છે—આ સ્લીક, SEO-મૈત્રીપર્વક URL માટે શ્રેષ્ઠ છે.

ભાગ 2 પૂરો કરવો

અમે હવે ઘણી વસ્તુઓ આવરી લીધી છે! તમારા બ્લોગ બેકએન્ડ હવે આવશ્યક ફંક્શન્સ, ટ્રિગરો, અને RLS નીતિઓ સાથે મજબૂત છે. આ સુધારણાઓ તમારું ડેટા સુરક્ષિત, સુસંગત, અને કાર્યક્ષમ રાખશે. ભાગ 3માં, અમે ગિયર બદલીશું અને રિએક્ટ, એસ્ટ્રો, અને ટેલવિન્ડ CSSનો ઉપયોગ કરીને ફ્રન્ટએન્ડ બનાવવા પર ધ્યાન કેન્દ્રિત કરીશું, જેથી આ બેકએન્ડની તમામ સારી વસ્તુઓ જીવંત બની શકે.

અહીં ક્લિક કરીને સંકલિત SQL ફાઇલ ડાઉનલોડ કરો


આગળ: ભાગ 3 – રિએક્ટ અને એસ્ટ્રો સાથે ફ્રન્ટએન્ડ બનાવવું
હવે કે તમારું બેકએન્ડ લૉકડ અને લોડેડ છે, તમારા બ્લોગને સુંદર અને પ્રતિસાદી ફ્રન્ટએન્ડ સાથે જીવંત બનાવવાનો સમય આવી ગયો છે. એસ્ટ્રો, રિએક્ટ, અને ટેલવિન્ડ CSSમાં ગહન રીતે ઘુસવા માટે તૈયાર રહો!


વધુ વાંચન

સુપાબેસની ક્ષમતાઓમાં વધુ ઊંડાણથી જાઓ? રો-લેવલ સુરક્ષા, ટ્રિગરો, અને અદ્યતન SQL ફંક્શન્સ વિશે વધુ શોધવા માટે સુપાબેસ ડોક્યુમેન્ટેશન તપાસો.