Probably easiest way to do this without major refactoring is to use the existing save mechanism.
Currently save client passes a "validate" param to the server which is either truthy/falsy.
What we can do is pass :validate_only in the valid param, and call (from the client) the save server side method (inisomorphic_base). This will run the whole save process which is wrapped in a transaction. At the bottom of the save method, it checks the save parameter. Right at that point it should first check the validate parameter and if it is :validate_only then raise and internally defined error class called ValidRollback. Then catch this error outside the transaction block, and report that the record is valid.
Likewise if an error is raised, then right at the normal rescue, we need to check and see if if the exception is because of an invalid record, capture what ever is invalid and report this back to the client.
summary of changes:
client side:
# instance methods module:
def valid?(&block)
@backing_record.valid?(&block)
end
def invalid?(&block)
if block
valid? { |valid| block.call !valid }
else
valid?.then { |valid| !valid } # I think.... maybe its Promise.new(!valid)
end
end
# isomorphic methods:
# add this method at about # line 331
def valid?(validate, &block)
models, associations, backing_records = self.class.gather_records([self], force, self)
backing_records.each { |id, record| record.saving! }
promise = Promise.new
HTTP.post(`window.ReactiveRecordEnginePath`+"/save",
payload: {
json: {
models: models,
associations: associations,
validate: :validate_only
}.to_json
}
).then do |response|
begin
response.json[:models] = response.json[:saved_models].collect do |item|
backing_records[item[0]].ar_instance
end
response.json[:saved_models].each do | item |
backing_records[item[0]].errors! item[3]
end
yield response.json[:valid] if block
promise.resolve response.json[:valid]
backing_records.each { |id, record| record.saved! }
end
promise
end
# approx line 538:
# add this check:
if validate == "validate_only" # I think this is a string at this point
Raise ValidationRollback
elsif save
{success: true, saved_models: saved_models }
else
vectors.each { |vector, model| model.reload unless model.nil? or model.new_record? or model.frozen? }
vectors
end
# approx line 551:
rescue ValidationRollback
{valid: true, valid_models: saved_models}
rescue Exception => e
if e.message == ""Could not save all models" && validate == "validate_only"
{valid: false, valid_models: saved_models}
else
...carry on
Probably easiest way to do this without major refactoring is to use the existing
save
mechanism.Currently save client passes a "validate" param to the server which is either truthy/falsy.
What we can do is pass
:validate_only
in thevalid
param, and call (from the client) thesave
server side method (inisomorphic_base
). This will run the whole save process which is wrapped in a transaction. At the bottom of the save method, it checks thesave
parameter. Right at that point it should first check thevalidate
parameter and if it is:validate_only
then raise and internally defined error class calledValidRollback
. Then catch this error outside the transaction block, and report that the record is valid.Likewise if an error is raised, then right at the normal rescue, we need to check and see if if the exception is because of an invalid record, capture what ever is invalid and report this back to the client.
summary of changes:
client side: