Class: HasHelpers::LimitFavorites

Inherits:
PsqlHq::Trigger
  • Object
show all
Defined in:
app/triggers/has_helpers/limit_favorites.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass:, limit:, **options) ⇒ LimitFavorites

Returns a new instance of LimitFavorites.



7
8
9
10
11
# File 'app/triggers/has_helpers/limit_favorites.rb', line 7

def initialize(klass:, limit:, **options)
  @klass = klass
  @limit = limit
  super(options)
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass.



5
6
7
# File 'app/triggers/has_helpers/limit_favorites.rb', line 5

def klass
  @klass
end

#limitObject (readonly)

Returns the value of attribute limit.



5
6
7
# File 'app/triggers/has_helpers/limit_favorites.rb', line 5

def limit
  @limit
end

Class Method Details

.constraint_trigger?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'app/triggers/has_helpers/limit_favorites.rb', line 17

def self.constraint_trigger?
  true
end

.data_trigger?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'app/triggers/has_helpers/limit_favorites.rb', line 21

def self.data_trigger?
  false
end

.drop_by_function_name(function_name) ⇒ Object



89
90
91
92
93
94
# File 'app/triggers/has_helpers/limit_favorites.rb', line 89

def drop_by_function_name(function_name)
  ::ActiveRecord::Base.connection.execute <<-SQL
    DROP FUNCTION IF EXISTS \"#{function_name}\"() CASCADE;
  SQL
  puts "-- Dropped #{function_name} (if it existed) and any dependent triggers"
end

.prefixObject



13
14
15
# File 'app/triggers/has_helpers/limit_favorites.rb', line 13

def self.prefix
  "FHQ"
end

.triggersObject



85
86
87
# File 'app/triggers/has_helpers/limit_favorites.rb', line 85

def triggers
  @triggers ||= []
end

Instance Method Details

#createObject



29
30
31
32
33
34
35
36
37
38
39
# File 'app/triggers/has_helpers/limit_favorites.rb', line 29

def create
  ::ActiveRecord::Base.connection.execute trigger_function

  ::ActiveRecord::Base.connection.execute <<-SQL
    CREATE CONSTRAINT TRIGGER "#{trigger_name}"
    AFTER INSERT OR UPDATE OF #{favorite_foreign_key} ON favorites DEFERRABLE INITIALLY DEFERRED
    FOR EACH ROW EXECUTE PROCEDURE "#{function_name}"();
  SQL

  puts "-- Created trigger #{trigger_name} and function #{function_name}."
end

#dropObject



41
42
43
# File 'app/triggers/has_helpers/limit_favorites.rb', line 41

def drop
  LimitFavorites.drop_by_function_name(function_name)
end

#nameObject



25
26
27
# File 'app/triggers/has_helpers/limit_favorites.rb', line 25

def name
  "limit_favorites_#{klass.table_name}"
end

#trigger_functionObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/triggers/has_helpers/limit_favorites.rb', line 45

def trigger_function
  <<-SQL
    CREATE OR REPLACE FUNCTION public."#{function_name}"() RETURNS TRIGGER LANGUAGE plpgsql AS $function$
      DECLARE
        row_limit INTEGER;
        nrows INTEGER;
        resource_id TEXT;
      BEGIN
        #{exit_if_skipped_sql}

        row_limit := #{limit};

        SELECT
          COUNT(*) INTO nrows
        FROM favorites
        WHERE favorites.created_by_id = NEW.created_by_id
        AND #{favorite_foreign_key} IS NOT NULL;

        IF nrows > row_limit THEN
          SELECT
            format('%s-%s', '#{favorite_foreign_key.titleize}', NEW.#{favorite_foreign_key}::text)
          INTO resource_id;

          RAISE NOTICE 'favorite limit: resource_id = %', resource_id;
          RAISE 'Exceeded favorite limit of % for %', row_limit, resource_id;
        END IF;

        RETURN NULL;
      END
    $function$;
  SQL
end