Skip to content

Instantly share code, notes, and snippets.

@mhenrixon
Created November 22, 2012 19:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhenrixon/4132566 to your computer and use it in GitHub Desktop.
Save mhenrixon/4132566 to your computer and use it in GitHub Desktop.
How to achieve rails counter_cache directly in the database.
CREATE TRIGGER update_task_counters
AFTER INSERT OR UPDATE OR DELETE ON tasks
FOR EACH ROW EXECUTE PROCEDURE update_task_counters();
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
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;
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