Skip to content

Instantly share code, notes, and snippets.

@ttanimichi
Created September 15, 2014 02:11
Show Gist options
  • Save ttanimichi/a968b70a5fc2302db944 to your computer and use it in GitHub Desktop.
Save ttanimichi/a968b70a5fc2302db944 to your computer and use it in GitHub Desktop.
乱数などを格納する列にUnique制約をかけた場合に、万が一衝突が発生したらリトライするモジュール
# depends on save, save!, create, create!
module RetryIfCollide
extend ActiveSupport::Concern
def save(*)
self.class._retry_if_collide { super }
end
def save!(*)
self.class._retry_if_collide { super }
end
module ClassMethods
def create(*)
_retry_if_collide { super }
end
def create!(*)
_retry_if_collide { super }
end
def _retry_if_collide
begin
tries ||= 3
yield
rescue ActiveRecord::RecordNotUnique => e
retry if (tries -= 1) > 0
fail "give up"
end
end
end
end
@ttanimichi
Copy link
Author

ActiveRecord::RecordNotUnique が発生した場合に、どの列が衝突したのか判定する手段がないので使用しなかった(idなどが衝突した場合でもリトライしてしまう & raiseするのがStandardErrorになってしまう)。e.messageをパースすればどの列が衝突したのか分かるが、そこまではやりたくない。

@ttanimichi
Copy link
Author

CreatingWithCode

# depends on self.code
module CreatingWithCode
  extend ActiveSupport::Concern

  included do
    before_create -> { self.code = RandomString.generate unless self.code }
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment