From 12cfeb2b7589d0b4fd44eac7c2267b4a1430c8f7 Mon Sep 17 00:00:00 2001 From: Syphax bouazzouni Date: Thu, 16 Mar 2023 02:48:32 +0100 Subject: [PATCH] Merge pull request #31 from ontoportal-lirmm/feature/add-models-on-update-callbacks Feature: Add models on update callbacks --- lib/goo/base/resource.rb | 29 +++++++++++++++-- lib/goo/base/settings/settings.rb | 10 ++++++ lib/goo/sparql/triples.rb | 10 ------ lib/goo/validators/enforce.rb | 15 +++++++++ test/test_update_callbacks.rb | 53 +++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 test/test_update_callbacks.rb diff --git a/lib/goo/base/resource.rb b/lib/goo/base/resource.rb index f4fe6c8f..2d11ca1a 100644 --- a/lib/goo/base/resource.rb +++ b/lib/goo/base/resource.rb @@ -220,10 +220,13 @@ def save(*opts) raise ArgumentError, "Enums can only be created on initialization" unless opts[0] && opts[0][:init_enum] end batch_file = nil - if opts && opts.length > 0 - if opts.first.is_a?(Hash) && opts.first[:batch] && opts.first[:batch].is_a?(File) + callbacks = true + if opts && opts.length > 0 && opts.first.is_a?(Hash) + if opts.first[:batch] && opts.first[:batch].is_a?(File) batch_file = opts.first[:batch] end + + callbacks = opts.first[:callbacks] end if !batch_file @@ -231,8 +234,28 @@ def save(*opts) raise Goo::Base::NotValidException, "Object is not valid. Check errors." unless valid? end + #set default values before saving + unless self.persistent? + self.class.attributes_with_defaults.each do |attr| + value = self.send("#{attr}") + if value.nil? + value = self.class.default(attr).call(self) + self.send("#{attr}=", value) + end + end + end + + #call update callback before saving + if callbacks + self.class.attributes_with_update_callbacks.each do |attr| + Goo::Validators::Enforce.enforce_callbacks(self, attr) + end + end + graph_insert, graph_delete = Goo::SPARQL::Triples.model_update_triples(self) - graph = self.graph() + graph = self.graph + + if graph_delete and graph_delete.size > 0 begin Goo.sparql_update_client.delete_data(graph_delete, graph: graph) diff --git a/lib/goo/base/settings/settings.rb b/lib/goo/base/settings/settings.rb index 3d343d5d..5f669d08 100644 --- a/lib/goo/base/settings/settings.rb +++ b/lib/goo/base/settings/settings.rb @@ -96,6 +96,16 @@ def attributes_with_defaults select{ |attr,opts| opts[:default] }).keys() end + def attributes_with_update_callbacks + (@model_settings[:attributes]. + select{ |attr,opts| opts[:onUpdate] }).keys + end + + + def update_callbacks(attr) + @model_settings[:attributes][attr][:onUpdate] + end + def default(attr) return @model_settings[:attributes][attr][:default] end diff --git a/lib/goo/sparql/triples.rb b/lib/goo/sparql/triples.rb index cb840df9..df3f9f1d 100644 --- a/lib/goo/sparql/triples.rb +++ b/lib/goo/sparql/triples.rb @@ -67,16 +67,6 @@ def self.model_update_triples(model) unless model.persistent? graph_insert << [subject, RDF.type, model.class.uri_type(model.collection)] end - #set default values before saving - if not model.persistent? - model.class.attributes_with_defaults.each do |attr| - value = model.send("#{attr}") - if value.nil? - value = model.class.default(attr).call(model) - model.send("#{attr}=",value) - end - end - end model.modified_attributes.each do |attr| next if model.class.collection?(attr) diff --git a/lib/goo/validators/enforce.rb b/lib/goo/validators/enforce.rb index 1a53eaf0..3c90e204 100644 --- a/lib/goo/validators/enforce.rb +++ b/lib/goo/validators/enforce.rb @@ -64,6 +64,17 @@ def enforce(inst,attr,value) errors_by_opt.length > 0 ? errors_by_opt : nil end + def enforce_callback(inst, attr) + callbacks = Array(inst.class.update_callbacks(attr)) + callbacks.each do |proc| + if instance_proc?(inst, proc) + call_proc(inst.method(proc), inst, attr) + elsif proc.is_a?(Proc) + call_proc(proc, inst, attr) + end + end + end + private def object_type(opt) @@ -115,6 +126,10 @@ def add_error(opt, err) def self.enforce(inst,attr,value) EnforceInstance.new.enforce(inst,attr,value) end + + def self.enforce_callbacks(inst, attr) + EnforceInstance.new.enforce_callback(inst, attr) + end end end end diff --git a/test/test_update_callbacks.rb b/test/test_update_callbacks.rb new file mode 100644 index 00000000..bef38a68 --- /dev/null +++ b/test/test_update_callbacks.rb @@ -0,0 +1,53 @@ +require_relative 'test_case' + + +require_relative 'models' + +class TestUpdateCallBack < Goo::Base::Resource + model :update_callback_model, name_with: :code + attribute :code, enforce: [:string, :existence] + attribute :name, enforce: [:string, :existence] + attribute :first_name, onUpdate: :update_name + attribute :last_name, onUpdate: :update_name + + + def update_name(inst, attr) + self.name = self.first_name + self.last_name + end +end + +class TestUpdateCallBacks < MiniTest::Unit::TestCase + + def self.before_suite + GooTestData.delete_all [TestUpdateCallBack] + end + + def self.after_suite + GooTestData.delete_all [TestUpdateCallBack] + end + + + def test_update_callback + p = TestUpdateCallBack.new + p.code = "1" + p.name = "name" + p.first_name = "first_name" + p.last_name = "last_name" + + assert p.valid? + p.save + + p.bring_remaining + + assert_equal p.first_name + p.last_name, p.name + + p.last_name = "last_name2" + p.save + + p.bring_remaining + assert_equal "last_name2", p.last_name + assert_equal p.first_name + p.last_name, p.name + end + +end +