NoBrainerORM / nobrainer

Ruby ORM for RethinkDB
http://nobrainer.io/
Other
386 stars 49 forks source link

API for pluggable create/update ReQL #227

Open robertjpayne opened 8 years ago

robertjpayne commented 8 years ago

I have quite a unique use case but I think it may be nice to have official support for rather than monkey patching.

Our application requires sync capabilities and to handle conflicts during writes I've devised a plan to atomically check a field while updating it like (sorry if syntax is not 100% correct):

update do |row|
  r.branch(
    row["timestamp"] < updateAttrs["timestamp"],
    updateAttrs,
    r.error("Invalid Update, timestamp is older than db")
  )
end

This would be pretty easy to if there was pluggable access to how the RQL query is generated for inserts/updates on a per-model-class basis.

nviennot commented 8 years ago

This is a good idea. I like it.

Any suggestions for the API?

robertjpayne commented 8 years ago

@nviennot I don't think it needs to be particularly crazy, just looking at code there is:

  def _create(options={})
    attrs = self.class.persistable_attributes(@_attributes)
    result = NoBrainer.run(self.class.rql_table.insert(attrs))
    self.pk_value ||= result['generated_keys'].to_a.first
    @new_record = false
    unlock_unique_fields # just an optimization for the uniquness validation
    true
  end

  def _update(attrs)
    rql = ->(doc){ self.class.persistable_attributes(attrs, :rql_doc => doc) }
    NoBrainer.run { selector.update(&rql) }
  end

Maybe all we need is a class method that is generate_insert_rql(attrs) and generate_update_rql(selector, attrs) which both return a block that is passed directly into NoBrainer.run?

Thoughts? Might not be the cleanest and I'm not 100% certain on functionality of the self.class.persistable_attributes.

robertjpayne commented 8 years ago

Closing this as it's just a bit too hefty to do so…

nviennot commented 8 years ago

Reopening because this usecase is common, and this needs to be addressed in some ways.