enju_biblio 0.3.16 → 0.3.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/app/models2/agent.rb +331 -0
  3. data/app/models2/agent_import_file.rb +259 -0
  4. data/app/models2/agent_import_file_state_machine.rb +19 -0
  5. data/app/models2/agent_import_file_transition.rb +20 -0
  6. data/app/models2/agent_import_result.rb +20 -0
  7. data/app/models2/agent_merge.rb +17 -0
  8. data/app/models2/agent_merge_list.rb +27 -0
  9. data/app/models2/agent_relationship.rb +24 -0
  10. data/app/models2/agent_relationship_type.rb +20 -0
  11. data/app/models2/agent_type.rb +19 -0
  12. data/app/models2/carrier_type.rb +50 -0
  13. data/app/models2/content_type.rb +19 -0
  14. data/app/models2/country.rb +47 -0
  15. data/app/models2/create.rb +29 -0
  16. data/app/models2/create_type.rb +19 -0
  17. data/app/models2/doi_record.rb +36 -0
  18. data/app/models2/donate.rb +15 -0
  19. data/app/models2/form_of_work.rb +19 -0
  20. data/app/models2/frequency.rb +19 -0
  21. data/app/models2/identifier.rb +83 -0
  22. data/app/models2/identifier_type.rb +18 -0
  23. data/app/models2/import_request.rb +77 -0
  24. data/app/models2/import_request_state_machine.rb +9 -0
  25. data/app/models2/import_request_transition.rb +21 -0
  26. data/app/models2/isbn_record.rb +51 -0
  27. data/app/models2/isbn_record_and_manifestation.rb +18 -0
  28. data/app/models2/issn_record.rb +49 -0
  29. data/app/models2/issn_record_and_manifestation.rb +18 -0
  30. data/app/models2/item.rb +173 -0
  31. data/app/models2/item_custom_property.rb +18 -0
  32. data/app/models2/item_custom_value.rb +17 -0
  33. data/app/models2/language.rb +39 -0
  34. data/app/models2/license.rb +18 -0
  35. data/app/models2/manifestation.rb +764 -0
  36. data/app/models2/manifestation_custom_property.rb +18 -0
  37. data/app/models2/manifestation_custom_value.rb +17 -0
  38. data/app/models2/manifestation_relationship.rb +27 -0
  39. data/app/models2/manifestation_relationship_type.rb +20 -0
  40. data/app/models2/medium_of_performance.rb +19 -0
  41. data/app/models2/own.rb +29 -0
  42. data/app/models2/periodical.rb +33 -0
  43. data/app/models2/periodical_and_manifestation.rb +16 -0
  44. data/app/models2/picture_file.rb +60 -0
  45. data/app/models2/produce.rb +30 -0
  46. data/app/models2/produce_type.rb +19 -0
  47. data/app/models2/realize.rb +29 -0
  48. data/app/models2/realize_type.rb +19 -0
  49. data/app/models2/resource_export_file.rb +64 -0
  50. data/app/models2/resource_export_file_state_machine.rb +15 -0
  51. data/app/models2/resource_export_file_transition.rb +21 -0
  52. data/app/models2/resource_import_file.rb +909 -0
  53. data/app/models2/resource_import_file_state_machine.rb +19 -0
  54. data/app/models2/resource_import_file_transition.rb +21 -0
  55. data/app/models2/resource_import_result.rb +24 -0
  56. data/app/models2/series_statement.rb +72 -0
  57. data/app/models2/series_statement_merge.rb +17 -0
  58. data/app/models2/series_statement_merge_list.rb +17 -0
  59. data/app/views/manifestations/_book_jacket.html.erb +9 -5
  60. data/app/views/manifestations/_colorbox.html.erb +1 -1
  61. data/app/views/manifestations/_pickup.html.erb +1 -1
  62. data/lib/enju_biblio/version.rb +1 -1
  63. data/spec/dummy/yarn.lock +7560 -0
  64. metadata +61 -2
@@ -0,0 +1,27 @@
1
+ class AgentMergeList < ApplicationRecord
2
+ has_many :agent_merges, dependent: :destroy
3
+ has_many :agents, through: :agent_merges
4
+ validates :title, presence: true
5
+
6
+ paginates_per 10
7
+
8
+ def merge_agents(selected_agent)
9
+ self.agents.each do |agent|
10
+ Create.where(agent_id: selected_agent.id).update_all(agent_id: agent.id)
11
+ Produce.where(agent_id: selected_agent.id).update_all(agent_id: agent.id)
12
+ Own.where(agent_id: selected_agent.id).update_all(agent_id: agent.id)
13
+ Donate.where(agent_id: selected_agent.id).update_all(agent_id: agent.id)
14
+ agent.destroy unless agent == selected_agent
15
+ end
16
+ end
17
+ end
18
+
19
+ # == Schema Information
20
+ #
21
+ # Table name: agent_merge_lists
22
+ #
23
+ # id :integer not null, primary key
24
+ # title :string
25
+ # created_at :datetime
26
+ # updated_at :datetime
27
+ #
@@ -0,0 +1,24 @@
1
+ class AgentRelationship < ApplicationRecord
2
+ belongs_to :parent, foreign_key: 'parent_id', class_name: 'Agent'
3
+ belongs_to :child, foreign_key: 'child_id', class_name: 'Agent'
4
+ belongs_to :agent_relationship_type, optional: true
5
+ validate :check_parent
6
+ acts_as_list scope: :parent_id
7
+
8
+ def check_parent
9
+ errors.add(:parent) if parent_id == child_id
10
+ end
11
+ end
12
+
13
+ # == Schema Information
14
+ #
15
+ # Table name: agent_relationships
16
+ #
17
+ # id :integer not null, primary key
18
+ # parent_id :integer
19
+ # child_id :integer
20
+ # agent_relationship_type_id :integer
21
+ # created_at :datetime
22
+ # updated_at :datetime
23
+ # position :integer
24
+ #
@@ -0,0 +1,20 @@
1
+ class AgentRelationshipType < ApplicationRecord
2
+ include MasterModel
3
+ default_scope { order('agent_relationship_types.position') }
4
+ has_many :agent_relationships
5
+ translates :display_name
6
+ end
7
+
8
+ # == Schema Information
9
+ #
10
+ # Table name: agent_relationship_types
11
+ #
12
+ # id :integer not null, primary key
13
+ # name :string not null
14
+ # old_display_name :text
15
+ # note :text
16
+ # position :integer
17
+ # created_at :datetime
18
+ # updated_at :datetime
19
+ # display_name_translations :jsonb not null
20
+ #
@@ -0,0 +1,19 @@
1
+ class AgentType < ApplicationRecord
2
+ include MasterModel
3
+ has_many :agents
4
+ translates :display_name
5
+ end
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: agent_types
10
+ #
11
+ # id :integer not null, primary key
12
+ # name :string not null
13
+ # old_display_name :text
14
+ # note :text
15
+ # position :integer
16
+ # created_at :datetime
17
+ # updated_at :datetime
18
+ # display_name_translations :jsonb not null
19
+ #
@@ -0,0 +1,50 @@
1
+ class CarrierType < ApplicationRecord
2
+ include MasterModel
3
+ has_many :manifestations
4
+ if ENV['ENJU_STORAGE'] == 's3'
5
+ has_attached_file :attachment, storage: :s3,
6
+ styles: { thumb: "16x16#" },
7
+ s3_credentials: {
8
+ access_key: ENV['AWS_ACCESS_KEY_ID'],
9
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
10
+ bucket: ENV['S3_BUCKET_NAME'],
11
+ s3_host_name: ENV['S3_HOST_NAME'],
12
+ s3_region: ENV['S3_REGION']
13
+ },
14
+ s3_permissions: :private
15
+ else
16
+ has_attached_file :attachment,
17
+ styles: { thumb: "16x16#" },
18
+ path: ":rails_root/private/system/:class/:attachment/:id_partition/:style/:filename"
19
+ end
20
+ validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\Z/
21
+ translates :display_name
22
+
23
+ def mods_type
24
+ case name
25
+ when 'volume'
26
+ 'text'
27
+ else
28
+ # TODO: その他のタイプ
29
+ 'software, multimedia'
30
+ end
31
+ end
32
+ end
33
+
34
+ # == Schema Information
35
+ #
36
+ # Table name: carrier_types
37
+ #
38
+ # id :integer not null, primary key
39
+ # name :string not null
40
+ # old_display_name :text
41
+ # note :text
42
+ # position :integer
43
+ # created_at :datetime
44
+ # updated_at :datetime
45
+ # attachment_file_name :string
46
+ # attachment_content_type :string
47
+ # attachment_file_size :bigint
48
+ # attachment_updated_at :datetime
49
+ # display_name_translations :jsonb not null
50
+ #
@@ -0,0 +1,19 @@
1
+ class ContentType < ApplicationRecord
2
+ include MasterModel
3
+ has_many :manifestations
4
+ translates :display_name
5
+ end
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: content_types
10
+ #
11
+ # id :integer not null, primary key
12
+ # name :string not null
13
+ # old_display_name :text
14
+ # note :text
15
+ # position :integer
16
+ # created_at :datetime
17
+ # updated_at :datetime
18
+ # display_name_translations :jsonb not null
19
+ #
@@ -0,0 +1,47 @@
1
+ class Country < ApplicationRecord
2
+ include MasterModel
3
+ default_scope { order('countries.position') }
4
+ has_many :agents
5
+ has_many :libraries
6
+ has_one :library_group
7
+
8
+ # If you wish to change the field names for brevity, feel free to enable/modify these.
9
+ # alias_attribute :iso, :alpha_2
10
+ # alias_attribute :iso3, :alpha_3
11
+ # alias_attribute :numeric, :numeric_3
12
+
13
+ # Validations
14
+ validates :alpha_2, :alpha_3, :numeric_3, presence: true
15
+ validates :name, presence: true, format: { with: /\A[0-9A-Za-z][0-9A-Za-z_\-\s,]*[0-9a-z]\Z/ }
16
+
17
+ after_save :clear_all_cache
18
+ after_destroy :clear_all_cache
19
+
20
+ def self.all_cache
21
+ Rails.cache.fetch('country_all'){Country.all.to_a}
22
+ end
23
+
24
+ def clear_all_cache
25
+ Rails.cache.delete('country_all')
26
+ end
27
+
28
+ private
29
+
30
+ def valid_name?
31
+ true
32
+ end
33
+ end
34
+
35
+ # == Schema Information
36
+ #
37
+ # Table name: countries
38
+ #
39
+ # id :integer not null, primary key
40
+ # name :string not null
41
+ # display_name :text
42
+ # alpha_2 :string
43
+ # alpha_3 :string
44
+ # numeric_3 :string
45
+ # note :text
46
+ # position :integer
47
+ #
@@ -0,0 +1,29 @@
1
+ class Create < ApplicationRecord
2
+ belongs_to :agent
3
+ belongs_to :work, class_name: 'Manifestation', foreign_key: 'work_id', touch: true
4
+ belongs_to :create_type, optional: true
5
+
6
+ validates :work_id, uniqueness: { scope: :agent_id }
7
+ after_save :reindex
8
+ after_destroy :reindex
9
+
10
+ acts_as_list scope: :work
11
+
12
+ def reindex
13
+ agent&.index
14
+ work&.index
15
+ end
16
+ end
17
+
18
+ # == Schema Information
19
+ #
20
+ # Table name: creates
21
+ #
22
+ # id :integer not null, primary key
23
+ # agent_id :integer not null
24
+ # work_id :integer not null
25
+ # position :integer
26
+ # created_at :datetime
27
+ # updated_at :datetime
28
+ # create_type_id :integer
29
+ #
@@ -0,0 +1,19 @@
1
+ class CreateType < ApplicationRecord
2
+ include MasterModel
3
+ default_scope { order('create_types.position') }
4
+ translates :display_name
5
+ end
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: create_types
10
+ #
11
+ # id :integer not null, primary key
12
+ # name :string
13
+ # old_display_name :text
14
+ # note :text
15
+ # position :integer
16
+ # created_at :datetime
17
+ # updated_at :datetime
18
+ # display_name_translations :jsonb not null
19
+ #
@@ -0,0 +1,36 @@
1
+ class DoiRecord < ApplicationRecord
2
+ belongs_to :manifestation
3
+ validates :body, presence: true, uniqueness: true, format: {with: /\A[0-9]{2}\.[0-9]{2,}\/.+\Z/}
4
+ before_save :normalize
5
+ before_save :set_display_body
6
+
7
+ strip_attributes
8
+
9
+ def normalize
10
+ url = URI.parse(body)
11
+ if url.host =~ /doi\.org\Z/
12
+ self.body = url.path.gsub(/\A\//, '').downcase
13
+ else
14
+ self.body = body.downcase
15
+ end
16
+ rescue URI::InvalidURIError
17
+ end
18
+
19
+ def set_display_body
20
+ self.display_body = body unless display_body
21
+ end
22
+ end
23
+
24
+ # == Schema Information
25
+ #
26
+ # Table name: doi_records
27
+ #
28
+ # id :bigint not null, primary key
29
+ # body :string not null
30
+ # display_body :string not null
31
+ # source :string
32
+ # response :jsonb not null
33
+ # manifestation_id :bigint not null
34
+ # created_at :datetime not null
35
+ # updated_at :datetime not null
36
+ #
@@ -0,0 +1,15 @@
1
+ class Donate < ApplicationRecord
2
+ belongs_to :agent
3
+ belongs_to :item
4
+ end
5
+
6
+ # == Schema Information
7
+ #
8
+ # Table name: donates
9
+ #
10
+ # id :integer not null, primary key
11
+ # agent_id :integer not null
12
+ # item_id :integer not null
13
+ # created_at :datetime
14
+ # updated_at :datetime
15
+ #
@@ -0,0 +1,19 @@
1
+ class FormOfWork < ApplicationRecord
2
+ include MasterModel
3
+ has_many :works, class_name: 'Manifestation' # , dependent: :restrict_with_exception
4
+ translates :display_name
5
+ end
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: form_of_works
10
+ #
11
+ # id :integer not null, primary key
12
+ # name :string not null
13
+ # old_display_name :text
14
+ # note :text
15
+ # position :integer
16
+ # created_at :datetime
17
+ # updated_at :datetime
18
+ # display_name_translations :jsonb not null
19
+ #
@@ -0,0 +1,19 @@
1
+ class Frequency < ApplicationRecord
2
+ include MasterModel
3
+ has_many :manifestations, dependent: :restrict_with_exception
4
+ translates :display_name
5
+ end
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: frequencies
10
+ #
11
+ # id :integer not null, primary key
12
+ # name :string not null
13
+ # old_display_name :text
14
+ # note :text
15
+ # position :integer
16
+ # created_at :datetime
17
+ # updated_at :datetime
18
+ # display_name_translations :jsonb not null
19
+ #
@@ -0,0 +1,83 @@
1
+ class Identifier < ApplicationRecord
2
+ belongs_to :identifier_type
3
+ belongs_to :manifestation, touch: true, optional: true
4
+
5
+ validates :body, presence: true
6
+ validates :body, uniqueness: { scope: [:identifier_type_id, :manifestation_id] }
7
+ validate :check_identifier
8
+ before_validation :normalize
9
+ before_save :convert_isbn
10
+ scope :id_type, -> type {
11
+ where(identifier_type: IdentifierType.find_by(name: type))
12
+ }
13
+
14
+ acts_as_list scope: :manifestation_id
15
+ strip_attributes only: :body
16
+
17
+ def check_identifier
18
+ case identifier_type&.name
19
+ when 'isbn'
20
+ unless StdNum::ISBN.valid?(body)
21
+ errors.add(:body)
22
+ end
23
+
24
+ when 'issn'
25
+ unless StdNum::ISSN.valid?(body)
26
+ errors.add(:body)
27
+ end
28
+
29
+ when 'lccn'
30
+ unless StdNum::LCCN.valid?(body)
31
+ errors.add(:body)
32
+ end
33
+
34
+ when 'doi'
35
+ if URI.parse(body).scheme
36
+ errors.add(:body)
37
+ end
38
+ end
39
+ end
40
+
41
+ def convert_isbn
42
+ if identifier_type.name == 'isbn'
43
+ lisbn = Lisbn.new(body)
44
+ if lisbn.isbn
45
+ if lisbn.isbn.length == 10
46
+ self.body = lisbn.isbn13
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def hyphenated_isbn
53
+ if identifier_type.name == 'isbn'
54
+ lisbn = Lisbn.new(body)
55
+ lisbn.parts.join('-')
56
+ end
57
+ end
58
+
59
+ def normalize
60
+ case identifier_type&.name
61
+ when 'isbn'
62
+ self.body = StdNum::ISBN.normalize(body)
63
+ when 'issn'
64
+ self.body = StdNum::ISSN.normalize(body)
65
+ when 'lccn'
66
+ self.body = StdNum::LCCN.normalize(body)
67
+ end
68
+ end
69
+ end
70
+
71
+ # == Schema Information
72
+ #
73
+ # Table name: identifiers
74
+ #
75
+ # id :integer not null, primary key
76
+ # body :string not null
77
+ # identifier_type_id :integer not null
78
+ # manifestation_id :integer
79
+ # primary :boolean
80
+ # position :integer
81
+ # created_at :datetime
82
+ # updated_at :datetime
83
+ #
@@ -0,0 +1,18 @@
1
+ class IdentifierType < ApplicationRecord
2
+ include MasterModel
3
+ has_many :identifiers
4
+ validates :name, format: { with: /\A[0-9a-z][0-9a-z_\-]*[0-9a-z]\Z/ }
5
+ end
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: identifier_types
10
+ #
11
+ # id :integer not null, primary key
12
+ # name :string
13
+ # display_name :text
14
+ # note :text
15
+ # position :integer
16
+ # created_at :datetime
17
+ # updated_at :datetime
18
+ #
@@ -0,0 +1,77 @@
1
+ class ImportRequest < ApplicationRecord
2
+ include Statesman::Adapters::ActiveRecordQueries[
3
+ transition_class: ImportRequestTransition,
4
+ initial_state: :pending
5
+ ]
6
+ default_scope { order('import_requests.id DESC') }
7
+ belongs_to :manifestation, optional: true
8
+ belongs_to :user
9
+ validates :isbn, presence: true
10
+ validate :check_isbn
11
+ #validate :check_imported, on: :create
12
+ #validates_uniqueness_of :isbn, if: Proc.new{|request| ImportRequest.where("created_at > ?", 1.day.ago).collect(&:isbn).include?(request.isbn)}
13
+
14
+ has_many :import_request_transitions, autosave: false
15
+
16
+ def state_machine
17
+ ImportRequestStateMachine.new(self, transition_class: ImportRequestTransition)
18
+ end
19
+
20
+ delegate :can_transition_to?, :transition_to!, :transition_to, :current_state,
21
+ to: :state_machine
22
+
23
+ def check_isbn
24
+ if isbn.present?
25
+ errors.add(:isbn) unless StdNum::ISBN.valid?(isbn)
26
+ end
27
+ end
28
+
29
+ def check_imported
30
+ if isbn.present?
31
+ identifier_type = IdentifierType.find_by_or_create!(name: 'isbn')
32
+ if Identifier.find_by(body: isbn, identifier_type_id: identifier_type.id)&.manifestation
33
+ errors.add(:isbn, I18n.t('import_request.isbn_taken'))
34
+ end
35
+ end
36
+ end
37
+
38
+ def import!
39
+ exceptions = [ ActiveRecord::RecordInvalid, NameError, URI::InvalidURIError ]
40
+ not_found_exceptions = []
41
+ not_found_exceptions << EnjuNdl::RecordNotFound if defined? EnjuNdl
42
+ not_found_exceptions << EnjuNii::RecordNotFound if defined? EnjuNii
43
+ begin
44
+ return nil unless Manifestation.respond_to?(:import_isbn)
45
+ unless manifestation
46
+ manifestation = Manifestation.import_isbn(isbn)
47
+ if manifestation
48
+ self.manifestation = manifestation
49
+ transition_to!(:completed)
50
+ manifestation.index
51
+ Sunspot.commit
52
+ else
53
+ transition_to!(:failed)
54
+ end
55
+ end
56
+ save
57
+ rescue *not_found_exceptions => e
58
+ transition_to!(:failed)
59
+ return :record_not_found
60
+ rescue *exceptions => e
61
+ transition_to!(:failed)
62
+ return :error
63
+ end
64
+ end
65
+ end
66
+
67
+ # == Schema Information
68
+ #
69
+ # Table name: import_requests
70
+ #
71
+ # id :integer not null, primary key
72
+ # isbn :string
73
+ # manifestation_id :integer
74
+ # user_id :integer
75
+ # created_at :datetime
76
+ # updated_at :datetime
77
+ #
@@ -0,0 +1,9 @@
1
+ class ImportRequestStateMachine
2
+ include Statesman::Machine
3
+
4
+ state :pending, initial: true
5
+ state :completed
6
+ state :failed
7
+
8
+ transition from: :pending, to: [:completed, :failed]
9
+ end
@@ -0,0 +1,21 @@
1
+ class ImportRequestTransition < ApplicationRecord
2
+ include Statesman::Adapters::ActiveRecordTransition
3
+
4
+
5
+ belongs_to :import_request, inverse_of: :import_request_transitions
6
+ #attr_accessible :to_state, :sort_key, :metadata
7
+ end
8
+
9
+ # == Schema Information
10
+ #
11
+ # Table name: import_request_transitions
12
+ #
13
+ # id :integer not null, primary key
14
+ # to_state :string
15
+ # metadata :text default({})
16
+ # sort_key :integer
17
+ # import_request_id :integer
18
+ # created_at :datetime
19
+ # updated_at :datetime
20
+ # most_recent :boolean not null
21
+ #
@@ -0,0 +1,51 @@
1
+ class IsbnRecord < ApplicationRecord
2
+ has_many :isbn_record_and_manifestations, dependent: :destroy
3
+ has_many :manifestations, through: :isbn_record_and_manifestations
4
+ before_save :normalize_isbn
5
+ validates :body, presence: true
6
+ strip_attributes
7
+
8
+ def self.new_records(isbn_records_params)
9
+ return [] unless isbn_records_params
10
+ isbn_records = []
11
+ IsbnRecord.transaction do
12
+ isbn_records_params.each do |k, v|
13
+ next if v['_destroy'] == '1'
14
+ if v['body'].present?
15
+ isbn_record = IsbnRecord.where(body: Lisbn.new(v['body'].gsub(/[^0-9x]/i, '')).isbn13).first_or_create!
16
+ elsif v['id'].present?
17
+ isbn_record = IsbnRecord.find(v['id'])
18
+ else
19
+ v.delete('_destroy')
20
+ isbn_record = IsbnRecord.create(v)
21
+ end
22
+ isbn_records << isbn_record
23
+ end
24
+ end
25
+ isbn_records
26
+ end
27
+
28
+ def normalize_isbn
29
+ if StdNum::ISBN.valid?(body)
30
+ self.body = StdNum::ISBN.normalize(body)
31
+ else
32
+ errors.add(:body)
33
+ end
34
+ end
35
+
36
+ def valid_isbn?
37
+ StdNum::ISBN.valid?(body)
38
+ end
39
+ end
40
+
41
+ # == Schema Information
42
+ #
43
+ # Table name: isbn_records
44
+ #
45
+ # id :bigint not null, primary key
46
+ # body :string not null
47
+ # isbn_type :string
48
+ # source :string
49
+ # created_at :datetime not null
50
+ # updated_at :datetime not null
51
+ #
@@ -0,0 +1,18 @@
1
+ class IsbnRecordAndManifestation < ApplicationRecord
2
+ belongs_to :isbn_record
3
+ belongs_to :manifestation
4
+ validates :isbn_record_id, uniqueness: {scope: :manifestation_id}
5
+ acts_as_list
6
+ end
7
+
8
+ # == Schema Information
9
+ #
10
+ # Table name: isbn_record_and_manifestations
11
+ #
12
+ # id :bigint not null, primary key
13
+ # isbn_record_id :bigint not null
14
+ # manifestation_id :bigint not null
15
+ # position :integer
16
+ # created_at :datetime not null
17
+ # updated_at :datetime not null
18
+ #
@@ -0,0 +1,49 @@
1
+ class IssnRecord < ApplicationRecord
2
+ has_many :issn_record_and_manifestations, dependent: :destroy
3
+ has_many :manifestations, through: :issn_record_and_manifestations
4
+ has_many :issn_record_and_periodicals, dependent: :destroy
5
+ has_many :periodicals, through: :issn_record_and_periodicals
6
+ validates :body, presence: true, uniqueness: {scope: :issn_type}
7
+ before_save :normalize_issn
8
+ strip_attributes
9
+
10
+ def normalize_issn
11
+ if StdNum::ISSN.valid?(body)
12
+ self.body = StdNum::ISSN.normalize(body)
13
+ else
14
+ errors.add(:body)
15
+ end
16
+ end
17
+
18
+ def self.new_records(issn_records_params)
19
+ return [] unless issn_records_params
20
+ issn_records = []
21
+ IssnRecord.transaction do
22
+ issn_records_params.each do |k, v|
23
+ next if v['_destroy'] == '1'
24
+ if v['body'].present?
25
+ issn_record = IssnRecord.where(body: v['body'].gsub(/[^0-9x]/i, '')).first_or_create!
26
+ elsif v['id'].present?
27
+ issn_record = IssnRecord.find(v['id'])
28
+ else
29
+ v.delete('_destroy')
30
+ issn_record = IssnRecord.create(v)
31
+ end
32
+ issn_records << issn_record
33
+ end
34
+ end
35
+ issn_records
36
+ end
37
+ end
38
+
39
+ # == Schema Information
40
+ #
41
+ # Table name: issn_records
42
+ #
43
+ # id :bigint not null, primary key
44
+ # body :string not null
45
+ # issn_type :string
46
+ # source :string
47
+ # created_at :datetime not null
48
+ # updated_at :datetime not null
49
+ #