Class: Identifier::Global::Isbn
- Inherits:
- 
      Identifier::Global
      
        - Object
- ActiveRecord::Base
- ApplicationRecord
- Identifier
- Identifier::Global
- Identifier::Global::Isbn
 
- Defined in:
- app/models/identifier/global/isbn.rb
Overview
Officially all ISBNs are now 13 digits - however anything published prior to 2007 may have a 10 digit format that requires special processing (see isbn.org) to convert a 10 digit ISBN to a 13 digit ISBN. For our purposes we will allow either a 10 digit or a 13 digit ISBN. - 1/31/2014
From the International ISBN Agency (isbn-international.org/faqs) on 1/31/2014:
Each ISBN consists of 5 parts with each section being separated by spaces or hyphens. Three of the five elements may be of varying length:
Prefix element – currently this can only be either 978 or 979 (it is always 3 digits).
Registration group element – this identifies the particular country, geographical region, or language area
  participating in the ISBN system. This element may be between 1 and 5 digits in length.
Registrant element - this identifies the particular publisher or imprint. This may be up to 7 digits in length.
Publication element – this identifies the particular edition and format of a specific title. This may be up to 6
  digits in length
Check digit – this is always the final single digit that mathematically validates the rest of the number.
  It is calculated using a Modulus 10 system with alternate weights of 1 and 3.
All of this means that it is difficult to validate an ISBN.
validations contains at least 10 digit & only digits, dashes, or spaces validates :identifier, :format => => /A*z/, :message => ‘Only digits, spaces and dashes allowed.’ doesn’t allow blank identifier, because can only create an object if it has an identifier.
Constant Summary
Constants included from SoftValidation
SoftValidation::ANCESTORS_WITH_SOFT_VALIDATIONS
Constants included from Shared::DualAnnotator
Shared::DualAnnotator::ALWAYS_COMMUNITY
Instance Attribute Summary
Attributes inherited from Identifier::Global
Attributes inherited from Identifier
#cached, #cached_numeric_identifier, #identifier, #identifier_object_id, #identifier_object_type, #namespace_id, #project_id, #type
Instance Method Summary collapse
Methods inherited from Identifier::Global
#build_cached, #dwc_occurrences, #is_global?, #sv_resolves?
Methods included from SoftValidation
#clear_soft_validations, #fix_for, #fix_soft_validations, #soft_fixed?, #soft_valid?, #soft_validate, #soft_validated?, #soft_validations, #soft_validators
Methods inherited from Identifier
#build_cached, #build_cached_numeric_identifier, #is_global?, #is_local?, namespaces_for_types_from_query, process_batch_by_filter_scope, prototype_identifier, #set_cached, #type_name
Methods included from Shared::IsData
#errors_excepting, #full_error_messages_excepting, #identical, #is_community?, #is_destroyable?, #is_editable?, #is_in_use?, #is_in_users_projects?, #metamorphosize, #similar
Methods included from Shared::Labels
Methods included from Housekeeping
#has_polymorphic_relationship?
Methods included from Shared::PolymorphicAnnotator
#annotated_object_is_persisted?
Methods inherited from ApplicationRecord
Instance Method Details
#ten_or_thirteen_digits? ⇒ Boolean
| 105 106 107 108 109 110 111 112 113 | # File 'app/models/identifier/global/isbn.rb', line 105 def ten_or_thirteen_digits? # @todo beth will talk to Jim when she gets back from vacation on how to correctly extract only the digits from the string. #count = 0 #carray = self.chars #carray.each do |c| # if c.is_digit? #end end | 
#using_isbn_class ⇒ Object
| 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | # File 'app/models/identifier/global/isbn.rb', line 27 def using_isbn_class unless identifier.nil? isbn = identifier.upcase # 'ISBN-13: 978-0-596-52068-7' isbn.gsub!('ISBN-10', '') type = $& isbn.gsub!('ISBN-13', '') type ||= $& type.gsub!('ISBN-', '') unless type.nil? isbn.gsub!('ISBN', '') # ': 978-0-596-52068-7' isbn.gsub!(':', '') # ' 978-0-596-52068-7' isbn.strip! # '978-0-596-52068-7' or '978 0 596 52068 7' # if there are spaces or hyphens, check to see that they are in the right places /^(\d{3}[ -]{0,1}){0,1}\d{1,5}[ -]{0,1}\d{1,5}[ -]{0,1}\d{1,5}[ -]{0,1}(?<last>.)$/ =~ isbn isbn.gsub!(' ', '') isbn.gsub!('-', '') # if there are *any* non-digits left, it is improperly formed # NB! 'X' is a valid digit in this case /[^\dX]/ =~ isbn unless $&.nil? errors.add(:identifier, "'#{identifier}' is an improperly formed ISBN.") return end # the final (checksum) digit has alreaqdy been identified, so we need 12 or 9 here /^(?<isbn_13>\d{12})\d$|^(?<isbn_10>\d{9}).$/ =~ isbn if ($&.nil?) or (isbn_10.nil? and isbn_13.nil?) or ((isbn_10.nil? and type == '10') or (isbn_13.nil? and type == '13')) errors.add(:identifier, "'#{identifier}' has the wrong number of digits.") return end data = isbn.slice(0, isbn.size - 1) sum = 0 index = 0 # last = 10 if last == 'X' if data.size == 9 data.reverse! data.each_char { |c| factor = (index + 2) sum += factor * c.to_i index += 1 } check_byte = 11 - (sum % 11) if check_byte == 10 check_byte = 'X' else if check_byte == 11 check_byte = 0 end end else data.each_char { |c| factor = (((index % 2) * 2) + 1) sum += factor * c.to_i index += 1 } check_byte = 10 - (sum % 10) if check_byte == 10 check_byte = 0; end end # check_byte and/or last might be an 'X' if check_byte.to_s != last errors.add(:identifier, "'#{identifier}' has bad check digit.") return end end end |