Created
November 22, 2012 19:04
-
-
Save mhenrixon/4132566 to your computer and use it in GitHub Desktop.
How to achieve rails counter_cache directly in the database.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE TRIGGER update_task_counters | |
AFTER INSERT OR UPDATE OR DELETE ON tasks | |
FOR EACH ROW EXECUTE PROCEDURE update_task_counters(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AddSomeTriggers < ActiveRecord::Migration | |
def change | |
execute "DROP TRIGGER IF EXISTS update_user_counters(userid integer);" | |
execute %q{ | |
CREATE OR REPLACE FUNCTION update_user_counters (userid integer) | |
RETURNS void AS $$ | |
BEGIN | |
update users set | |
tasks_count = coalesce((select count(9) from tasks where user_id = userid and completed = 'f'), 0) | |
where id = userid; | |
END; | |
$$ LANGUAGE plpgsql; | |
} | |
execute "DROP FUNCTION IF EXISTS update_task_counters;" | |
execute %q{ | |
CREATE OR REPLACE FUNCTION update_task_counters() | |
RETURNS trigger AS $update_task_counters$ | |
BEGIN | |
IF (tg_op = 'UPDATE') THEN | |
IF new.completed <> old.completed THEN | |
PERFORM update_user_counters(new.user_id); | |
END IF; | |
return new; | |
ELSIF (tg_op = 'INSERT') then | |
PERFORM update_user_counters(new.user_id); | |
RETURN new; | |
ELSIF (tg_op = 'DELETE') then | |
PERFORM update_user_counters(new.user_id); | |
RETURN null; | |
END IF; | |
RETURN null; | |
END; | |
$update_task_counters$ LANGUAGE plpgsql; | |
} | |
execute "DROP TRIGGER IF EXISTS update_task_counters;" | |
execute %q{ | |
CREATE TRIGGER update_task_counters | |
AFTER INSERT OR UPDATE OR DELETE ON tasks | |
FOR EACH ROW EXECUTE PROCEDURE update_task_counters(); | |
} | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE OR REPLACE FUNCTION update_task_counters() | |
RETURNS trigger AS $update_task_counters$ | |
BEGIN | |
IF (tg_op = 'UPDATE') THEN | |
IF new.completed <> old.completed THEN | |
PERFORM update_user_counters(new.user_id); | |
END IF; | |
return new; | |
ELSIF (tg_op = 'INSERT') then | |
PERFORM update_user_counters(new.user_id); | |
RETURN new; | |
ELSIF (tg_op = 'DELETE') then | |
PERFORM update_user_counters(new.user_id); | |
RETURN null; | |
END IF; | |
RETURN null; | |
END; | |
$update_task_counters$ LANGUAGE plpgsql; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE OR REPLACE FUNCTION update_user_counters (userid integer) | |
RETURNS void AS $$ | |
BEGIN | |
update users set | |
tasks_count = coalesce((select count(9) from tasks where user_id = userid and completed = 'f'), 0) | |
where id = userid; | |
END; | |
$$ LANGUAGE plpgsql; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment