Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding new merging logic

  • Loading branch information...
commit 136d132435e74f6e62fc4f418b18e957a17552a4 1 parent bd8bf12
@Bringo Bringo authored
View
56 app/models/asset.rb
@@ -1,6 +1,5 @@
class Asset < ActiveRecord::Base
include PbcoreXmlElement
- include Merge
before_create :generate_uuid
after_save :save_version
@@ -330,30 +329,37 @@ def merge_existing
# IMPORTANT: Any changes to models or the schema might affect this code.
# CHECK THIS WHEN THE SCHEMA CHANGES!
def merge(new_asset)
- merge!(new_asset)
- # [:identifiers, :titles, :asset_dates, :descriptions, :relations, :coverages, :creators, :contributors,
- # :publishers, :rights_summaries, :instantiations, :annotations, :extensions].each do |field|
- # current_fields = self.send(field)
- # new_fields = new_asset.send(field)
- #
- # current_attrs = current_fields.map { |o| clean_attributes(o.attributes) }
- #
- # # this is O(n²), but hopefully n is small enough that this isn't a huge problem
- # new_fields.each do |fields|
- # Rails.logger.debug { "MERGE (#{field.to_s}): current_attrs: #{current_attrs.inspect}" }
- # Rails.logger.debug { "MERGE (#{field.to_s}): new_field: #{clean_attributes(fields.attributes).inspect}"}
- # unless current_attrs.include?(clean_attributes(fields.attributes))
- # Rails.logger.debug { "--- MERGING (#{field.to_s}) ---" }
- # current_fields << fields
- # else
- # Rails.logger.debug { "--- NOT MERGING (#{field.to_s})" }
- # end
- # end
- # end
- #
- # [:genre_ids, :subject_ids, :audience_level_ids, :audience_rating_ids].each do |field|
- # self.send("#{field}=".to_sym, self.send(field) | new_asset.send(field))
- # end
+ [:identifiers, :titles, :asset_dates, :descriptions, :relations, :coverages, :creators, :contributors,
+ :publishers, :rights_summaries, :instantiations, :annotations, :extensions].each do |field|
+
+ current_fields = self.send(field)
+ new_fields = new_asset.send(field)
+
+ current_attrs = current_fields.map { |o| clean_attributes(o.attributes) }
+
+ # this is O(n²), but hopefully n is small enough that this isn't a huge problem
+ new_fields.each do |fields|
+ if field == :instantiations
+ # Check if there is format identifier source that has auto merge set
+ if format_id = fields.format_ids.detect { |format_id| format_id.format_identifier_source.auto_merge == true }
+ # Does the existing record have a format identifier source that matches
+ # if current_format_id = current_fields.format_ids.detect { |current_format_id| format_id.format_identifier_source.name == format_id.format_identifier_source.name }
+ if current_instantiation = self.send(field).find(:first, :include => :format_ids, :conditions => ["format_ids.format_identifier_source_id = ? and format_ids.format_identifier = ?", format_id.format_identifier_source_id, format_id.format_identifier])
+ # Destroy the current instantiation and import the new one
+ current_instantiation.destroy
+ end
+ # Just import the new instantiation
+ current_fields << fields
+ end
+ else
+ current_fields << fields unless current_attrs.include?(clean_attributes(fields.attributes))
+ end
+ end
+ end
+
+ [:genre_ids, :subject_ids, :audience_level_ids, :audience_rating_ids].each do |field|
+ self.send("#{field}=".to_sym, self.send(field) | new_asset.send(field))
+ end
end
def self.xmlify_import_results(results)
View
9 db/migrate/20120111212907_add_auto_merge_to_format_identifier_sources.rb
@@ -0,0 +1,9 @@
+class AddAutoMergeToFormatIdentifierSources < ActiveRecord::Migration
+ def self.up
+ add_column :format_identifier_sources, :auto_merge, :boolean, :default => false
+ end
+
+ def self.down
+ remove_column :format_identifier_sources, :auto_merge
+ end
+end
View
26 db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20111231225416) do
+ActiveRecord::Schema.define(:version => 20120111212907) do
create_table "annotations", :force => true do |t|
t.integer "container_id"
@@ -251,6 +251,15 @@
add_index "essence_tracks", ["instantiation_id"], :name => "index_essence_tracks_on_instantiation_id"
+ create_table "exports", :force => true do |t|
+ t.string "status"
+ t.string "file"
+ t.integer "creator_id"
+ t.integer "updater_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "extension_names", :force => true do |t|
t.string "extension_key"
t.string "extension_authority"
@@ -273,9 +282,10 @@
add_index "extensions", ["asset_id"], :name => "index_extensions_on_asset_id"
create_table "format_identifier_sources", :force => true do |t|
- t.string "name", :null => false
- t.boolean "visible", :default => false, :null => false
+ t.string "name", :null => false
+ t.boolean "visible", :default => false, :null => false
t.string "regex"
+ t.boolean "auto_merge", :default => false
end
create_table "format_ids", :force => true do |t|
@@ -331,8 +341,8 @@
t.datetime "updated_at"
t.integer "creator_id"
t.integer "updater_id"
- t.text "annotation"
t.text "ref"
+ t.text "annotation"
end
add_index "identifiers", ["asset_id"], :name => "index_identifiers_on_asset_id"
@@ -448,6 +458,14 @@
add_index "ip_blocks", ["name"], :name => "index_ip_blocks_on_name", :unique => true
+ create_table "pbcore_importers", :force => true do |t|
+ t.string "file"
+ t.integer "number_of_records"
+ t.integer "number_of_records_processed"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "publisher_roles", :force => true do |t|
t.string "name", :null => false
t.boolean "visible", :default => false, :null => false
View
94 lib/merge.rb
@@ -1,94 +0,0 @@
-module Merge
-
- # True if self is safe to merge with +object+, ie they are more or less equal.
- # Default implementation compares all attributes except id and metadata.
- # Can be overridden in specific models that have a neater way of comparison.
- def merge_equal?(object)
- object.instance_of?(self.class) and merge_attributes == object.merge_attributes
- end
-
- MERGE_INDIFFERENT_ATTRIBUTES = %w(id position created_at updated_at creator_id updater_id uuid).freeze
- MERGE_EXCLUDE_ASSOCIATIONS = [].freeze
-
- # Attribute hash used for comparison.
- def merge_attributes
- merge_attribute_names.inject({}) do |attrs, name|
- attrs[name] = self[name]
- attrs
- end
- end
-
- # Names of the attributes that should be merged.
- def merge_attribute_names
- attribute_names - MERGE_INDIFFERENT_ATTRIBUTES
- end
-
- # Names of associations excluded from the merge.
- # Override if the model has multiple scoped associations,
- # that can all be retrieved by a single has_many association.
- def merge_exclude_associations
- MERGE_EXCLUDE_ASSOCIATIONS
- end
-
- # Merge this object with the given +objects+.
- # This object will serve as the master,
- # blank attributes will be taken from the given objects, in order.
- # All associations to +objects+ will be assigned to +self+.
- def merge!(*objects)
- transaction do
- merge_attributes!(*objects)
- merge_association_reflections.each do |r|
- local = send(r.name)
- objects.each do |object|
- if r.macro == :has_one
- other = object.send(r.name)
- if local and other
- local.merge!(other)
- elsif other
- send("#{r.name}=", other)
- end
- else
- other = object.send(r.name) - local
- # May be better to compare without the primary key attribute instead of setting it.
- other.each {|o| o[r.primary_key_name] = self.id}
- other.reject! {|o| local.any? {|l| merge_if_equal(l,o) }}
- local << other
- end
- end
- end
- objects.each {|o| o.reload and o.destroy unless o.new_record?}
- end
- end
-
- def merge_attributes!(*objects)
- blank_attributes = merge_attribute_names.select {|att| self[att].blank?}
- until blank_attributes.empty? or objects.empty?
- object = objects.shift
- blank_attributes.reject! do |att|
- if val = object[att] and not val.blank?
- self[att] = val
- end
- end
- end
- save!
- end
-
- private
-
- def merge_association_reflections
- self.class.reflect_on_all_associations.select do |r|
- [:has_many, :has_one, :has_and_belongs_to_many].include?(r.macro) and
- not r.options[:through] and
- not merge_exclude_associations.include?(r.name.to_sym)
- end
- end
-
- def merge_if_equal(master, object)
- if master.merge_equal?(object)
- master.merge!(object) ; true
- end
- end
-
-end
-
-ActiveRecord::Base.class_eval { include Merge }
Please sign in to comment.
Something went wrong with that request. Please try again.