Class: Subject

Inherits:
Record show all
Defined in:
backend/app/model/subject.rb,
public/app/models/subject.rb

Constant Summary

Constants inherited from Record

Record::ABSTRACT

Instance Attribute Summary

Attributes inherited from Record

#agents, #classifications, #container_display, #container_summary_for_badge, #container_titles_and_uris, #criteria, #dates, #display_string, #extents, #external_documents, #full, #highlights, #identifier, #json, #lang_materials, #level, #linked_digital_objects, #notes, #other_level, #primary_type, #raw, #repository_information, #resolved_repository, #resolved_resource, #resolved_top_container, #subjects, #uri

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Record

#[], #apply_highlighting, #dig, #initialize, #note, #parse_full_title, #request_item

Constructor Details

This class inherits a constructor from Record

Class Method Details

.create_from_json(json, opts = {}) ⇒ Object



75
76
77
78
# File 'backend/app/model/subject.rb', line 75

def self.create_from_json(json, opts = {})
  set_vocabulary(json, opts)
  super(json, opts.merge(:terms_sha1 => generate_terms_sha1(json)))
end

.ensure_exists(json, referrer) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'backend/app/model/subject.rb', line 81

def self.ensure_exists(json, referrer)
  DB.attempt {
    self.create_from_json(json)
  }.and_if_constraint_fails {|exception|
    subject = find_matching(json)

    if !subject
      # The subject exists but we can't find it.  This could mean it was
      # created in a currently running transaction.  Abort this one to trigger
      # a retry.
      Log.info("Subject '#{json.terms}' seems to have been created by a currently running transaction.  Restarting this one.")
      sleep 5
      raise RetryTransaction.new
    end

    subject
  }
end

.find_matching(json) ⇒ Object



101
102
103
104
105
106
107
# File 'backend/app/model/subject.rb', line 101

def self.find_matching(json)
  source_id = BackendEnumSource.id_for_value("subject_source", json.source)

  Subject.find(:vocab_id => JSONModel(:vocabulary).id_for(json.vocabulary),
               :terms_sha1 => generate_terms_sha1(json),
               :source_id => source_id)
end

.generate_terms_sha1(json) ⇒ Object



68
69
70
71
72
# File 'backend/app/model/subject.rb', line 68

def self.generate_terms_sha1(json)
  return nil if json.terms.empty?

  Digest::SHA1.hexdigest(json.terms.map {|term| [term['term'], term['term_type']]}.inspect)
end

.handle_delete(ids_to_delete) ⇒ Object



141
142
143
144
145
# File 'backend/app/model/subject.rb', line 141

def self.handle_delete(ids_to_delete)
  self.db[:subject_term].filter(:subject_id => ids_to_delete).delete

  super
end

.sequel_to_jsonmodel(objs, opts = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'backend/app/model/subject.rb', line 117

def self.sequel_to_jsonmodel(objs, opts = {})
  jsons = super

  if opts[:calculate_linked_repositories]
    subjects_to_repositories = GlobalRecordRepositoryLinkages.new(self, :subject).call(objs)

    jsons.zip(objs).each do |json, obj|
      json.used_within_repositories = subjects_to_repositories.fetch(obj, []).map {|repo| repo.uri}
      json.used_within_published_repositories = subjects_to_repositories.fetch(obj, []).select {|repo| repo.publish == 1}.map {|repo| repo.uri}
    end
  end


  publication_status = ImpliedPublicationCalculator.new.for_subjects(objs)

  jsons.zip(objs).each do |json, obj|
    json.vocabulary = uri_for(:vocabulary, obj.vocab_id)
    json.is_linked_to_published_record = publication_status.fetch(obj)
  end

  jsons
end

.set_vocabulary(json, opts) ⇒ Object



59
60
61
62
63
64
65
# File 'backend/app/model/subject.rb', line 59

def self.set_vocabulary(json, opts)
  opts["vocab_id"] = nil

  if json.vocabulary
    opts["vocab_id"] = parse_reference(json.vocabulary, opts)[:id]
  end
end

Instance Method Details

#update_from_json(json, opts = {}, apply_nested_records = true) ⇒ Object



110
111
112
113
114
# File 'backend/app/model/subject.rb', line 110

def update_from_json(json, opts = {}, apply_nested_records = true)
  self.class.set_vocabulary(json, opts)
  self[:terms_sha1] = self.class.generate_terms_sha1(json) # add a terms sha1 hash to allow for uniqueness test
  super
end

#validateObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'backend/app/model/subject.rb', line 148

def validate
  super

  if self[:source_id]
    validates_unique([:vocab_id, :source_id, :terms_sha1], :message => "Subject must be unique")
  else
    validates_unique([:vocab_id, :terms_sha1], :message => "Subject must be unique")
  end

  validates_unique([:vocab_id, :source_id, :authority_id], :message => "Subject heading identifier must be unique within source")
  map_validation_to_json_property([:vocab_id, :source_id, :authority_id], :authority_id)
  map_validation_to_json_property([:vocab_id, :terms_sha1], :terms)
  map_validation_to_json_property([:vocab_id, :source_id, :terms_sha1], :terms)
end