Skip to content

Instantly share code, notes, and snippets.

View armstrjare's full-sized avatar

Jared Armstrong armstrjare

View GitHub Profile
@armstrjare
armstrjare / ActionMailer mail with DelayedJob.rb
Created January 21, 2010 04:01
Simply make Mailer.deliver_xxx_email(args) dispatch to delayed job to send, but still generate the mail content locally.
class DelayedJobMailer
def self.apply!
ActionMailer::Base.class_eval do
class << self
def method_missing_with_delayed_job_mailer(name, *args)
# This file monkey patches ActiveRecord to fix the problem of:
#
# MoodelA <-> ModelB <-> ModelC
# ModelA.joins(:modelb) & ModelB.joins(:modelc)
# -> Would raise association not found because the association ("modelc") is searched for
# -> from the context of ModelA, rather than from the [expected] context of ModelB
# (expected because the joins associatin is specified where the association "modelc" exists within the base of the Relation (ModelB) )
# -> The reason this ocurred is because the context of the joins on associations are not persisted when merging two relations/scopes
# -> rather, they are simply copied by name in to the merging relation/scope.
#
# AssociationProxy causes ActiveRecord#reload to re-run the finder-sql based on the association.
# Since we clear the invite_id on the Flatmate record when accepting an invite, this can cause difficult bugs
# to track down -- since flatmate.reload won't work! So we eliminate the issue entirely by ensuring we are always
# dealing with the actual target object (which reloads based on the primary key of the table) rather than
# potentially an AssociationProxy (which reloads based on the foreign key of the association)
def flatmate_with_proxy_removal(reload = nil)
r = flatmate_without_proxy_removal(reload); r && r.respond_to?(:target) ? r.target : r
end
alias_method_chain :flatmate, :proxy_removal
@armstrjare
armstrjare / resque_async.rb
Created November 5, 2010 10:55
UNTESTED... draft
# Provide a simple API for performing methods asynchronously on objects.
#
# Two approaches:
# 1) like DelayedJob's "delay" method
# my_obj.async.some_blocking_method(1, 2)
#
# 2) like DelayedJob's handle_asynchronously helper
# class Blah < ActiveRecord::Base
# extend ResqueAsync
# be_async :some_blocking_method
class Array
# Splits or iterates over the array in groups of size +number+,
# padding any remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7).in_groups_of(3) {|group| p group}
# ["1", "2", "3"]
# ["4", "5", "6"]
# ["7", nil, nil]
#
# %w(1 2 3).in_groups_of(2, '&nbsp;') {|group| p group}
@armstrjare
armstrjare / redis_pipeline_buffer.rb
Created March 4, 2011 01:42
Buffer redis pipeline calls, which flush on definable intervals.
# Helper class for buffering pipelined redis calls
#
# Options:
# - flush_at : The number of commands to keep in the buffer before flushing.
# A value of 1 will flush after every call.
# A value of 0 will *never* flush (must call flush! explicitly)
#
# Usage:
# redis_pipeline = RedisPipeline.new(redis_client, :flush_at => 50)
#
@armstrjare
armstrjare / polymorphic_entity.rb
Created March 26, 2011 21:37
Defines a bunch of helper methods for polymorphic associations.
module PolymorphicEntity
module ActiveRecordExtension
# Defines a bunch of helper methods for polymorphic associations.
def has_polymorphic_entity(*associations)
associations.each do |assoc|
# def sender_entity
@armstrjare
armstrjare / continuation_catch_throw.rb
Created July 16, 2011 11:42
A proof of concept that Ruby's native catch/throw can be [almost*] re-implemented using Ruby continuations.
# A proof of concept that Ruby's native catch/throw can be [almost*] re-implemented in Ruby.
#
# * begin/ensure semantics don't work when calling a Continuation
# -- so, unfortunately this implementation is not semantically equivalent to Ruby's native version :( But still cool nonetheless
module ContinuationCatchThrow
require 'continuation' unless defined?(Continuation)
# Emulate ruby Kernel#catch
def my_catch(tag = Object.new, &blk)
@armstrjare
armstrjare / rails_autosave_fix_monkeypatch.rb
Created October 15, 2011 06:15
Temporary monkeypatch to fix a bug with ActiveRecord::AutosaveAssociation until it's fixed upstream.
module ActiveRecord
module AutosaveAssociationFix
private
def associated_records_to_validate_or_save(*)
# There exists a case (new_record) where the returned array is actually the internal collection array.
# Unfortunately, this now gets mutated when records are removed. This means use of mark_for_destruction
# (to prevent creation of built records) can result in some records not being iterated over (and
# consequently not saved) on creation.
super.try(:dup)
end
# Monkey-patch routing layer to prevent Rails blindly using Object#inspect in generating error messages.
# This fixes super slow error responses on our app which has a large set of routes :)
# FIXME: We should remove this once Rails fixes this issue.
module ActionDispatch
module Routing
class RouteSet
alias inspect to_s
end
end
end