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, #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?, 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 |