acts_as_sourceable 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metadata +3 -9
- data/.gitignore +0 -2
- data/README.rdoc +0 -3
- data/acts_as_sourceable.gemspec +0 -13
- data/lib/acts_as_sourceable/acts_as_sourceable.rb +0 -121
- data/lib/acts_as_sourceable/sourceable_institution.rb +0 -16
- data/lib/acts_as_sourceable.rb +0 -4
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_sourceable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -18,13 +18,7 @@ email: technical@rrnpilot.org
|
|
18
18
|
executables: []
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files: []
|
21
|
-
files:
|
22
|
-
- .gitignore
|
23
|
-
- README.rdoc
|
24
|
-
- acts_as_sourceable.gemspec
|
25
|
-
- lib/acts_as_sourceable.rb
|
26
|
-
- lib/acts_as_sourceable/acts_as_sourceable.rb
|
27
|
-
- lib/acts_as_sourceable/sourceable_institution.rb
|
21
|
+
files: []
|
28
22
|
homepage: http://github.com/rrn/acts_as_sourceable
|
29
23
|
licenses: []
|
30
24
|
post_install_message:
|
@@ -45,7 +39,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
39
|
version: '0'
|
46
40
|
requirements: []
|
47
41
|
rubyforge_project:
|
48
|
-
rubygems_version: 1.8.
|
42
|
+
rubygems_version: 1.8.10
|
49
43
|
signing_key:
|
50
44
|
specification_version: 3
|
51
45
|
summary: perform garbage collection on categories that are no longer referenced
|
data/.gitignore
DELETED
data/README.rdoc
DELETED
data/acts_as_sourceable.gemspec
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = 'acts_as_sourceable'
|
3
|
-
s.version = '1.0.2'
|
4
|
-
s.date = %q{2010-09-16}
|
5
|
-
s.email = 'technical@rrnpilot.org'
|
6
|
-
s.homepage = 'http://github.com/rrn/acts_as_sourceable'
|
7
|
-
s.summary = 'perform garbage collection on categories that are no longer referenced'
|
8
|
-
s.description = 'Allows the RRN to perform garbage collection on categories that are no longer referenced.'
|
9
|
-
s.authors = ['Nicholas Jakobsen', 'Ryan Wallace']
|
10
|
-
|
11
|
-
s.files = `git ls-files`.split("\n")
|
12
|
-
s.require_paths = ["lib"]
|
13
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
module ActsAsSourceable
|
2
|
-
module ActMethod
|
3
|
-
def acts_as_sourceable(options = {})
|
4
|
-
# Include Class and Instance Methods
|
5
|
-
ActiveRecord::Relation.send(:include, ActsAsSourceable::ActiveRelationMethods)
|
6
|
-
extend ActsAsSourceable::ClassMethods
|
7
|
-
include ActsAsSourceable::InstanceMethods
|
8
|
-
|
9
|
-
has_many :sourceable_institutions, :as => :sourceable, :dependent => :destroy
|
10
|
-
has_many :sources, :through => :sourceable_institutions, :source => :holding_institution
|
11
|
-
|
12
|
-
# Delegate the relation methods to the relation
|
13
|
-
class << self
|
14
|
-
delegate :update_sources, :unsource, :to => :scoped
|
15
|
-
end
|
16
|
-
|
17
|
-
cattr_accessor :sourceable_cache_column, :sourceable_used_by, :sourceable_sourced_by
|
18
|
-
self.sourceable_cache_column = options[:cache_column]
|
19
|
-
self.sourceable_used_by = options[:used_by]
|
20
|
-
self.sourceable_sourced_by = options[:sourced_by]
|
21
|
-
|
22
|
-
# If a cache column is provided, use that to determine which records are sourced and unsourced
|
23
|
-
# Elsif the records can be derived, we need to check the flattened item tables for any references
|
24
|
-
# Else we check the sourceable_institutions to see if the record has a recorded source
|
25
|
-
if sourceable_cache_column
|
26
|
-
scope :sourced, where(sourceable_cache_column => true)
|
27
|
-
scope :unsourced, where(sourceable_cache_column => false)
|
28
|
-
else
|
29
|
-
scope :sourced, joins(:sourceable_institutions).group("#{table_name}.id")
|
30
|
-
scope :unsourced, joins("LEFT OUTER JOIN sourceable_institutions ON sourceable_id = #{quoted_table_name}.id and sourceable_type = '#{self.name}'").where("sourceable_id IS NULL")
|
31
|
-
end
|
32
|
-
|
33
|
-
# Create a scope that returns record that is not used by the associations in sourceable_used_by
|
34
|
-
if sourceable_used_by
|
35
|
-
scope :unused, where(Array(sourceable_used_by).collect {|usage_association| "id NOT IN (" + select("#{table_name}.id").joins(usage_association).group("#{table_name}.id").to_sql + ")"}.join(' AND '))
|
36
|
-
scope :orphaned, unsourced.unused
|
37
|
-
else
|
38
|
-
scope :orphaned, unsourced
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
module ActiveRelationMethods
|
44
|
-
def update_sources
|
45
|
-
scoping { @klass.find_each(&:update_sources) }
|
46
|
-
end
|
47
|
-
|
48
|
-
def unsource
|
49
|
-
scoping { @klass.update_all("#{sourceable_cache_column} = false", @klass.sourceable_cache_column => true) } if @klass.sourceable_cache_column
|
50
|
-
scoping { SourceableInstitution.where("sourceable_type = ? AND sourceable_id IN (#{@klass.select(:id).to_sql})", @klass.name).delete_all }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
module ClassMethods
|
55
|
-
def acts_like_sourceable?
|
56
|
-
true
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
module InstanceMethods
|
61
|
-
def acts_like_sourceable?
|
62
|
-
true
|
63
|
-
end
|
64
|
-
|
65
|
-
# Automatically update the sources for this model
|
66
|
-
# If the model gets its sources from another model, collect the sources of that model and record them as your own
|
67
|
-
# Else, this model must belong to a holding institution, so that is the source
|
68
|
-
def update_sources
|
69
|
-
if sourceable_sourced_by
|
70
|
-
if self.class.reflect_on_association(sourceable_sourced_by.to_sym).collection?
|
71
|
-
source_id_sql = send(sourceable_sourced_by).joins(:sourceable_institutions).select("sourceable_institutions.holding_institution_id").to_sql
|
72
|
-
sources = HoldingInstitution.where("id IN (#{source_id_sql})")
|
73
|
-
set_sources(sources)
|
74
|
-
else
|
75
|
-
set_sources(send(sourceable_sourced_by).sources)
|
76
|
-
end
|
77
|
-
else
|
78
|
-
set_sources(holding_institution)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def sourced?
|
83
|
-
if sourceable_cache_column
|
84
|
-
self[sourceable_cache_column]
|
85
|
-
else
|
86
|
-
self.class.sourced.exists?(self)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def unsourced?
|
91
|
-
!sourced?
|
92
|
-
end
|
93
|
-
|
94
|
-
# NOTE: We do a much more verbose method of assigning sources than the obvious self.sources = Array(holding_institutions)
|
95
|
-
# because HoldingInstitutions are present in the production database, and assigning sources causes rails to use the
|
96
|
-
# production database (as opposed to the conversion database) to check for existing sources. This is obviously bad
|
97
|
-
# because the sources in the production database do not reflect those that are in the conversion database since we
|
98
|
-
# unsource many things during conversion.
|
99
|
-
def set_sources(holding_institutions)
|
100
|
-
holding_institution_ids = Array(holding_institutions).collect(&:id)
|
101
|
-
existing_source_ids = self.class.connection.select_values(self.sourceable_institutions.select('sourceable_institutions.holding_institution_id').to_sql).collect(&:to_i)
|
102
|
-
|
103
|
-
# Delete those that have been removed
|
104
|
-
SourceableInstitution.where(:sourceable_type => self.class.name, :sourceable_id => self.id).delete_all(['holding_institution_id NOT IN (?)', holding_institution_ids])
|
105
|
-
|
106
|
-
# Add those that are not present
|
107
|
-
holding_institution_ids.each do |holding_institution_id|
|
108
|
-
self.sourceable_institutions << SourceableInstitution.new(:holding_institution_id => holding_institution_id) unless existing_source_ids.include?(holding_institution_id)
|
109
|
-
end
|
110
|
-
|
111
|
-
set_sourceable_cache_column(holding_institutions.present?)
|
112
|
-
end
|
113
|
-
|
114
|
-
private
|
115
|
-
|
116
|
-
def set_sourceable_cache_column(value)
|
117
|
-
# Update via sql because we don't need callbacks and validations called
|
118
|
-
self.class.update_all({sourceable_cache_column => value}, :id => id) if sourceable_cache_column
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
class SourceableInstitution < ActiveRecord::Base
|
2
|
-
belongs_to :sourceable, :polymorphic => true
|
3
|
-
belongs_to :holding_institution
|
4
|
-
|
5
|
-
validates_presence_of :sourceable_type, :sourceable_id, :holding_institution_id
|
6
|
-
|
7
|
-
# Removes sourceable institutions that no longer belong to a record or holding institution
|
8
|
-
def self.garbage_collect
|
9
|
-
ActiveRecord::Base.connection.select_values(SourceableInstitution.select("DISTINCT sourceable_type").to_sql).each do |sourceable_type|
|
10
|
-
sourceable_table_name = sourceable_type.constantize.table_name
|
11
|
-
sourceable_id_sql = SourceableInstitution.select("sourceable_institutions.id").where(:sourceable_type => sourceable_type).joins("LEFT OUTER JOIN #{sourceable_table_name} ON #{sourceable_table_name}.id = sourceable_institutions.sourceable_id").where("#{sourceable_table_name}.id IS NULL").to_sql
|
12
|
-
SourceableInstitution.delete_all("id IN (#{sourceable_id_sql})")
|
13
|
-
end
|
14
|
-
SourceableInstitution.delete_all(["holding_institution_id NOT IN (?)", HoldingInstitution.all.collect(&:id)])
|
15
|
-
end
|
16
|
-
end
|
data/lib/acts_as_sourceable.rb
DELETED