diff --git a/app/jobs/camelcase_nested_objects_by_id_job.rb b/app/jobs/camelcase_nested_objects_by_id_job.rb new file mode 100644 index 000000000..0b13971ce --- /dev/null +++ b/app/jobs/camelcase_nested_objects_by_id_job.rb @@ -0,0 +1,7 @@ +class CamelcaseNestedObjectsByIdJob < ActiveJob::Base + queue_as :lupo_background + + def perform(uuid, options = {}) + Event.camelcase_nested_objects(uuid) + end +end diff --git a/app/jobs/event_registrant_update_by_id_job.rb b/app/jobs/event_registrant_update_by_id_job.rb index 45cc4bc78..68e2a5fe5 100644 --- a/app/jobs/event_registrant_update_by_id_job.rb +++ b/app/jobs/event_registrant_update_by_id_job.rb @@ -19,7 +19,7 @@ def perform(id, options={}) registrant_id = get_crossref_member_id(item.obj_id) end - obj = item.obj.merge("registrant_id" => registrant_id) unless registrant_id.nil? + obj = item.obj.merge("registrantId" => registrant_id) unless registrant_id.nil? Rails.logger.info obj.inspect item.update_attributes(obj: obj) if obj.present? when "crossref" diff --git a/app/models/event.rb b/app/models/event.rb index c65cd4030..46b736505 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -546,6 +546,40 @@ def self.subj_id_check(options = {}) end end + def self.modify_nested_objects(options = {}) + size = (options[:size] || 1000).to_i + cursor = [options[:from_id], options[:until_id]] + + response = Event.query(nil, page: { size: 1, cursor: [] }) + Rails.logger.info "[modify_nested_objects] #{response.results.total} events for source datacite-crossref." + + # walk through results using cursor + if response.results.total.positive? + while response.results.results.length.positive? + response = Event.query(nil, page: { size: size, cursor: cursor }) + break unless response.results.results.length.positive? + + Rails.logger.info "[modify_nested_objects] modify_nested_objects #{response.results.results.length} events starting with _id #{response.results.to_a.first[:_id]}." + cursor = response.results.to_a.last[:sort] + Rails.logger.info "[modify_nested_objects] Cursor: #{cursor} " + + ids = response.results.results.map(&:uuid).uniq + ids.each do |id| + CamelcaseNestedObjectsByIdJob.perform_later(id, options) + end + end + end + end + + def self.camelcase_nested_objects(uuid) + event = Event.find_by(uuid: uuid) + if event.present? + subj = event.subj.transform_keys { |key| key.to_s.underscore.camelcase(:lower) } + obj = event.obj.transform_keys { |key| key.to_s.underscore.camelcase(:lower) } + event.update_attributes(subj: subj, obj: obj) + end + end + def self.label_state_event(event) subj_prefix = event[:subj_id][/(10\.\d{4,5})/, 1] unless Prefix.where(uid: subj_prefix).exists? @@ -625,7 +659,7 @@ def uuid_format end def registrant_id - [subj["registrant_id"], obj["registrant_id"], subj["provider_id"], obj["provider_id"]].compact + [subj["registrantId"], obj["registrantId"], subj["providerId"], obj["providerId"]].compact end def subtype @@ -681,8 +715,8 @@ def obj_cache_key def citation_year "" unless (INCLUDED_RELATION_TYPES + RELATIONS_RELATION_TYPES).include?(relation_type_id) - subj_publication = subj["date_published"] || (date_published(subj_id) || year_month) - obj_publication = obj["date_published"] || (date_published(obj_id) || year_month) + subj_publication = subj["datePublished"] || subj["date_published"] || (date_published(subj_id) || year_month) + obj_publication = obj["datePublished"] || obj["date_published"] || (date_published(obj_id) || year_month) [subj_publication[0..3].to_i, obj_publication[0..3].to_i].max end @@ -742,6 +776,10 @@ def set_defaults self.subj = subj.to_h.merge("id" => self.subj_id) self.obj = obj.to_h.merge("id" => self.obj_id) + ### makes keys camel case to match JSONAPI + self.subj.transform_keys! { |key| key.to_s.underscore.camelcase(:lower) } + self.obj.transform_keys! { |key| key.to_s.underscore.camelcase(:lower) } + self.total = 1 if total.blank? self.relation_type_id = "references" if relation_type_id.blank? self.occurred_at = Time.zone.now.utc if occurred_at.blank? diff --git a/lib/tasks/event.rake b/lib/tasks/event.rake index 0d18d05cd..4e0fe1164 100644 --- a/lib/tasks/event.rake +++ b/lib/tasks/event.rake @@ -100,6 +100,16 @@ namespace :crossref_events do end end +namespace :modify_nested_objects do + desc 'changes casing of nested objects in the database' + task :check => :environment do + from_id = (ENV['FROM_ID'] || Event.minimum(:id)).to_i + until_id = (ENV['UNTIL_ID'] || Event.maximum(:id)).to_i + + Event.modify_nested_objects(from_id: from_id, until_id: until_id) + end +end + namespace :datacite_crossref do desc 'Import crossref dois for all events' task :import_doi => :environment do diff --git a/spec/factories/default.rb b/spec/factories/default.rb index eb6585f61..03c1b5e33 100644 --- a/spec/factories/default.rb +++ b/spec/factories/default.rb @@ -374,7 +374,7 @@ source_id { "datacite_related" } source_token { "datacite_related_123" } sequence(:subj_id) { |n| "http://doi.org/10.5061/DRYAD.47SD5e/#{n}" } - subj { { "datePublished" => "2006-06-13T16:14:19Z" } } + subj { { "date_published" => "2006-06-13T16:14:19Z", "registrant_id" => "datacite.datacite" } } obj_id { "http://doi.org/10.5061/DRYAD.47SD5/1" } relation_type_id { "references" } end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 358bcd0ba..3d060ed8a 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -71,4 +71,13 @@ # end # end end + + describe "camelcase_nested_objects" do + subject { create(:event_for_datacite_related) } + + it "should transform keys" do + Event.camelcase_nested_objects(subject.uuid) + expect(subject.subj.keys).to include("datePublished", "registrantId", "id") + end + end end diff --git a/spec/requests/events_spec.rb b/spec/requests/events_spec.rb index 3415e8d91..5e5c8d0cf 100644 --- a/spec/requests/events_spec.rb +++ b/spec/requests/events_spec.rb @@ -266,6 +266,34 @@ expect(json.dig("meta", "registrants", 0, "id")).to eq("datacite.crossref.citations") end end + + context "with nested attrtibutes" do + let(:uri) { "/events" } + let(:params) do + { "data" => { "type" => "events", + "attributes" => { + "subjId" => "https://doi.org/10.18713/jimis-170117-1-2", + "subj" => { "@id":"https://doi.org/10.18713/jimis-170117-1-2", "@type":"ScholarlyArticle", "datePublished":"2017", "proxyIdentifiers":[], "registrantId":"datacite.inist.umr7300" }, + "obj" => { "@id":"https://doi.org/10.1016/j.jastp.2013.05.001", "@type":"ScholarlyArticle", "datePublished":"2013-09", "proxyIdentifiers":["13646826"], "registrantId":"datacite.crossref.citations" }, + "objId" => "https://doi.org/10.1016/j.jastp.2013.05.001", + "relationTypeId" => "references", + "sourceId" => "datacite-crossref", + "sourceToken" => "sourceToken" } } } + end + + it "are correctly stored" do + post uri, params, headers + + + expect(last_response.status).to eq(201) + puts json.dig("data", "id") + event = Event.where(uuid: json.dig("data", "id")).first + puts event.inspect + expect(event[:obj].has_key?('datePublished')).to be_truthy + expect(event[:obj].has_key?('registrantId')).to be_truthy + expect(event[:obj].has_key?('proxyIdentifiers')).to be_truthy + end + end end context "upsert" do