Skip to content

Instantly share code, notes, and snippets.

@ProGM
Last active March 1, 2016 15:44
Show Gist options
  • Save ProGM/6ebe6c2ca3756521c674 to your computer and use it in GitHub Desktop.
Save ProGM/6ebe6c2ca3756521c674 to your computer and use it in GitHub Desktop.
A patch to allow `neo4j` gem to retry when there's a `id_property` conflict.
class Article
include Neo4j::ActiveNode
include IdPropertyWithRetry
id_property :uuid, on: :id_builder, retry: 3
def id_builder
SecureRandom.urlsafe_base64(8)
end
end
Article.new.save
# => Article 18ms MATCH (n:`Article`) WHERE (n.uuid = {n_uuid}) RETURN n | {:n_uuid=>"conflicting_uuid"}
# => Article 18ms MATCH (n:`Article`) WHERE (n.uuid = {n_uuid}) RETURN n | {:n_uuid=>"valid_uuid"}
# => CYPHER 4ms CREATE (n:`Article` {props}) RETURN ID(n) | {:props=>{:uuid=>"valid_uuid"}}
module IdPropertyWithRetry
extend ActiveSupport::Concern
module ClassMethods
def id_property(name, conf = {})
conf[:on] = define_retry_methods(conf[:on], conf[:retry]) if conf[:on] && conf[:retry]
super
end
private
def define_retry_methods(name, times)
alias_name = :"#{name}_with_retry"
define_method(alias_name) do
counter = 0
generated = __send__(name)
while counter < times && self.class.as(:n).where(uuid: generated).any?
counter += 1
generated = __send__(name)
end
generated
end
alias_name
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment