Created
September 15, 2014 02:11
-
-
Save ttanimichi/a968b70a5fc2302db944 to your computer and use it in GitHub Desktop.
乱数などを格納する列にUnique制約をかけた場合に、万が一衝突が発生したらリトライするモジュール
This file contains hidden or 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
# 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 |
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
ActiveRecord::RecordNotUnique
が発生した場合に、どの列が衝突したのか判定する手段がないので使用しなかった(id
などが衝突した場合でもリトライしてしまう &raise
するのがStandardError
になってしまう)。e.message
をパースすればどの列が衝突したのか分かるが、そこまではやりたくない。