I'm trying to get Clearance to work with AWS Dynamo as the back-end store. The problem I'm having is that I can't get Clearance to not do the email-uniqueness validation, which it can't do because it's not able to do standard ActiveRecord uniqueness validations via a SQL query.
According to the comments in the code, I should be able to have my User
object return email_optional?
true
, and that should disable the uniqueness validation on emails. So I have:
class User < ApplicationRecord
include Dynamoid::Document
include Clearance::User
field :name
field :email
def email_optional?
puts 'yes, email is optional'
true
end
end
But, when I try to create a user I get an error, and, more to the point, the puts
is not executed:
$ rails c
Running via Spring preloader in process 18665
Loading development environment (Rails 5.1.3)
irb(main):001:0> u = User.new(name: 'ijd', email: 'ian@fu.bar', password: 'test')
ActiveRecord::StatementInvalid: Could not find table 'editor_development_users'
from (irb):1
Update: the reply from @spickermann reminded me that I should have noted that I also tried without subclassing ActiveRecord::Base
(via ApplicationRecord
). It gives a different error:
class User
include Dynamoid::Document
....
irb(main):002:0> reload!
Reloading...
=> true
irb(main):003:0> u = User.new(name: 'ijd', email: 'ian@fu.bar', password: 'test')
ArgumentError: Unknown validator: 'UniquenessValidator'
from app/models/user.rb:4:in `include'
from app/models/user.rb:4:in `<class:User>'
from app/models/user.rb:2:in `<top (required)>'
from (irb):3
User.new
does not trigger validations. Therefore the error cannot be connected to the validations itself.
At the moment your User
model is kind of both: A subclass of ActiveRecord::Base
and it behaves like a Dynamoid::Document
.
class User < ApplicationRecord
include Dynamoid::Document
# ...
end
ActiveRecord::Base
reads the table definition from the database when an instance is initialized. This leads to your exception, because the table does not exist. Just remove the inheritance from ApplicationRecord
.
class User
include Dynamoid::Document
# ...
end
The second issue when you remove the inheritance is more complex. Usually, I would suggest to just include ActiveModel::Validations
when you want to validate models that do not inherit from ActiveRecord::Base
. But the UniquenessValidator
isn't defined in ActiveModel::Validations
but in ActiveRecord::Validations
(what makes kind of sense). This makes Clearance
incompatible with models that do not inherit from ActiveRecord::Base
.
I would probably define a dummy implementation of a UniquenessValidator
as a work-around:
class User
include Dynamoid::Document
class UniquenessValidator
def initialize(_options); end
def def validate_each(_record, _attribute, _value); end
end
# ...
end