Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Empty ids #118
This has caught me twice and I know it's due to bugs in my code, but it would be nice to have an earlier warning. NoBrainer will happily save a document with id='' (empty string). This happens only once, of course, since the next time around it will fail the uniqueness requirement for ids.
However, I cannot possibly think of an actual use for this behavior, and it would be helpful if an exception was raised (or error added for ?-suffix methods) when the document is saved. This will make it easier to detect the error in user code and fix it before there's a dangling document in the database.
Obligatory example code:
require 'nobrainer' NoBrainer.configure do |config| config.rethinkdb_url = 'rethinkdb://localhost/nobrainer_playground' config.logger = Logger.new $stdout end class Foo include NoBrainer::Document end Foo.delete_all f = Foo.new id: '' f.save puts f.id # empty!
According to your comment on #109
It's unclear whether we should allow the empty string as an id based on that.
Here's what I suggest:
@ajselvig What do you think?
I actually think
My mental model is that setting
On a boolean field, it would be weird—the only thing I can think of is the classic "I agree to the terms and conditions" box, which of course most applications probably don't save as part of the
But it seems nice to have a single straightforward definition of
@nviennot I think that's probably a good solution. I guess I was thinking of id as a special field, different from the regular validations, but this works as well.
@mbrock Can you provide a situation where the ActiveModel required behavior for booleans is actually useful? It seems like you're specifying that a field can have only one possible value, so it might as well be a constant. Plus, this is a common source of confusion to those not familiar with the implementation.
Booleans in Ruby are ternary: true, false, and nil. By implementing the required validation the way we have, it becomes binary (and still useful).
Matching ActiveModel for the sake of matching it seems misguided. I like that NoBrainer chooses features that are useful and offer the least surprise. Besides, the ActiveModel reasoning for having this behavior seems to be "it lets us implement the validation with one function". Seems weak.
I'm currently working on a NoBrainer adapter for rails_admin, which seems to make me biased in favor of having similar behaviors across different ORMs. But of course, we are aren't working with a common standard, and we probably don't want to.
Since the ActiveModel behavior for required booleans is so weird and seemingly useless, and since they have decided that they don't want to change it, I wouldn't mind deviating from it.
The NoBrainer.io documentation currently states that:
But I guess all that would have to change is the explanation of the
So the non nil vs presence validator discussion makes sense only for String, Text, Binary, Array, Hash, Object, Boolean. The other types have the same behavior.
So we all agree that for Boolean, we want non nil, otherwise, it's not useful.
For Object, we'll do whatever is convenient to make the definition of
Which leaves us with Array, Hash, which should behave the same. I don't think there is a clear cut to what it possibly could mean.
I like this, it's good way to think about it.
The easiest definition that kind of fits everything well and will be easy to remember is:
For the required stuff: 8e7f108
However, I couldn't just add a
Okay so I took a closer look, and validators add validation callbacks. So I'd have to remove callbacks when removing the default definition of the primary key. Here's the code that clear all the callbacks: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/callbacks.rb#L715 -- doesn't look so fun.
So I'm not going to add the validation on the primary key. However, if you'd like to add such validation on all models in your own project, you can stick that in an initializer in your app:
module ValidatePrimaryKey extend ActiveSupport::Concern included do field :id, :required => true end NoBrainer::Document.__send__(:include, self) end