sufia-models 6.2.0 → 6.3.0
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.
- checksums.yaml +4 -4
- data/app/actors/sufia/generic_file/actor.rb +4 -7
- data/app/jobs/active_fedora_id_based_job.rb +1 -1
- data/app/jobs/active_fedora_pid_based_job.rb +1 -2
- data/app/jobs/audit_job.rb +1 -1
- data/app/jobs/batch_update_job.rb +6 -6
- data/app/jobs/create_derivatives_job.rb +2 -3
- data/app/jobs/import_url_job.rb +8 -5
- data/app/jobs/ingest_local_file_job.rb +1 -1
- data/app/models/batch.rb +15 -21
- data/app/models/checksum_audit_log.rb +0 -1
- data/app/models/concerns/sufia/ability.rb +5 -0
- data/app/models/concerns/sufia/collection_behavior.rb +3 -2
- data/app/models/concerns/sufia/file_stat_utils.rb +19 -21
- data/app/models/concerns/sufia/generic_file/batches.rb +1 -3
- data/app/models/concerns/sufia/generic_file/characterization.rb +11 -16
- data/app/models/concerns/sufia/generic_file/content.rb +0 -1
- data/app/models/concerns/sufia/generic_file/derivatives.rb +2 -2
- data/app/models/concerns/sufia/generic_file/export.rb +50 -59
- data/app/models/concerns/sufia/generic_file/full_text_indexing.rb +15 -18
- data/app/models/concerns/sufia/generic_file/metadata.rb +0 -2
- data/app/models/concerns/sufia/generic_file/mime_types.rb +9 -9
- data/app/models/concerns/sufia/generic_file/permissions.rb +0 -1
- data/app/models/concerns/sufia/generic_file/proxy_deposit.rb +0 -1
- data/app/models/concerns/sufia/generic_file/querying.rb +9 -5
- data/app/models/concerns/sufia/generic_file/trophies.rb +1 -1
- data/app/models/concerns/sufia/generic_file/versions.rb +0 -4
- data/app/models/concerns/sufia/model_methods.rb +0 -1
- data/app/models/concerns/sufia/user.rb +15 -15
- data/app/models/concerns/sufia/user_usage_stats.rb +0 -2
- data/app/models/datastreams/fits_datastream.rb +25 -25
- data/app/models/domain_term.rb +2 -3
- data/app/models/featured_work.rb +3 -5
- data/app/models/file_download_stat.rb +3 -4
- data/app/models/file_usage.rb +10 -11
- data/app/models/file_view_stat.rb +3 -3
- data/app/models/follow.rb +1 -1
- data/app/models/geo_names_resource.rb +3 -3
- data/app/models/group.rb +1 -3
- data/app/models/local_authority.rb +26 -28
- data/app/models/proxy_deposit_request.rb +9 -9
- data/app/models/single_use_link.rb +10 -18
- data/app/models/sufia/download.rb +2 -2
- data/app/models/sufia/pageview.rb +1 -1
- data/app/models/trophy.rb +2 -4
- data/app/services/sufia/analytics.rb +10 -11
- data/app/services/sufia/generic_file_audit_service.rb +11 -12
- data/app/services/sufia/repository_audit_service.rb +1 -1
- data/config/locales/sufia.en.yml +2 -0
- data/lib/generators/sufia/models/abstract_migration_generator.rb +7 -6
- data/lib/generators/sufia/models/install_generator.rb +3 -3
- data/lib/generators/sufia/models/templates/config/arkivo_constraint.rb +1 -1
- data/lib/generators/sufia/models/templates/config/clamav.rb +1 -1
- data/lib/generators/sufia/models/templates/config/redis_config.rb +13 -5
- data/lib/generators/sufia/models/templates/config/resque_admin.rb +2 -2
- data/lib/generators/sufia/models/templates/config/resque_config.rb +1 -1
- data/lib/generators/sufia/models/templates/config/sufia.rb +10 -4
- data/lib/generators/sufia/models/templates/migrations/create_checksum_audit_logs.rb +1 -1
- data/lib/generators/sufia/models/templates/migrations/create_file_download_stats.rb +1 -1
- data/lib/generators/sufia/models/templates/migrations/create_file_view_stats.rb +1 -1
- data/lib/generators/sufia/models/templates/migrations/create_local_authorities.rb +1 -1
- data/lib/generators/sufia/models/update_content_blocks_generator.rb +0 -1
- data/lib/generators/sufia/models/upgrade600_generator.rb +0 -1
- data/lib/generators/sufia/models/user_stats_generator.rb +2 -2
- data/lib/sufia/messages.rb +17 -17
- data/lib/sufia/models.rb +1 -1
- data/lib/sufia/models/active_fedora/redis.rb +1 -4
- data/lib/sufia/models/active_record/redis.rb +2 -3
- data/lib/sufia/models/engine.rb +12 -7
- data/lib/sufia/models/file_content/versions.rb +0 -1
- data/lib/sufia/models/resque.rb +2 -2
- data/lib/sufia/models/stats/user_stat_importer.rb +65 -67
- data/lib/sufia/models/user_local_directory_behavior.rb +9 -13
- data/lib/sufia/models/utils.rb +1 -2
- data/lib/sufia/models/version.rb +1 -1
- data/lib/sufia/permissions.rb +0 -1
- data/lib/sufia/permissions/readable.rb +0 -1
- data/lib/sufia/permissions/writable.rb +20 -23
- data/lib/tasks/sufia-models_tasks.rake +18 -0
- data/sufia-models.gemspec +1 -1
- metadata +5 -5
@@ -14,30 +14,27 @@ module Sufia
|
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
logger.error("Error extracting content from #{self.id}: #{e.inspect}")
|
30
|
-
end
|
17
|
+
def extract_content
|
18
|
+
uri = URI("#{connection_url}/update/extract?extractOnly=true&wt=json&extractFormat=text")
|
19
|
+
req = Net::HTTP.new(uri.host, uri.port)
|
20
|
+
resp = req.post(uri.to_s, content.content, 'Content-type' => "#{mime_type};charset=utf-8",
|
21
|
+
'Content-Length' => content.content.size.to_s)
|
22
|
+
raise "URL '#{uri}' returned code #{resp.code}" unless resp.code == "200"
|
23
|
+
content.content.rewind if content.content.respond_to?(:rewind)
|
24
|
+
extracted_text = JSON.parse(resp.body)[''].rstrip
|
25
|
+
full_text.content = extracted_text if extracted_text.present?
|
26
|
+
rescue => e
|
27
|
+
logger.error("Error extracting content from #{id}: #{e.inspect}")
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
|
30
|
+
def connection_url
|
31
|
+
case
|
34
32
|
when Blacklight.connection_config[:url] then Blacklight.connection_config[:url]
|
35
33
|
when Blacklight.connection_config["url"] then Blacklight.connection_config["url"]
|
36
34
|
when Blacklight.connection_config[:fulltext] then Blacklight.connection_config[:fulltext]["url"]
|
37
35
|
else Blacklight.connection_config[:default]["url"]
|
36
|
+
end
|
38
37
|
end
|
39
|
-
end
|
40
|
-
|
41
38
|
end
|
42
39
|
end
|
43
40
|
end
|
@@ -4,7 +4,6 @@ module Sufia
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
|
8
7
|
property :label, predicate: ActiveFedora::RDF::Fcrepo::Model.downloadFilename, multiple: false
|
9
8
|
|
10
9
|
property :depositor, predicate: ::RDF::URI.new("http://id.loc.gov/vocabulary/relators/dpt"), multiple: false do |index|
|
@@ -95,7 +94,6 @@ module Sufia
|
|
95
94
|
end
|
96
95
|
type ::RDF::URI.new('http://pcdm.org/models#Object')
|
97
96
|
end
|
98
|
-
|
99
97
|
end
|
100
98
|
end
|
101
99
|
end
|
@@ -4,23 +4,23 @@ module Sufia
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
def pdf?
|
7
|
-
self.class.pdf_mime_types.include?
|
7
|
+
self.class.pdf_mime_types.include? mime_type
|
8
8
|
end
|
9
9
|
|
10
10
|
def image?
|
11
|
-
self.class.image_mime_types.include?
|
11
|
+
self.class.image_mime_types.include? mime_type
|
12
12
|
end
|
13
13
|
|
14
14
|
def video?
|
15
|
-
self.class.video_mime_types.include?
|
15
|
+
self.class.video_mime_types.include? mime_type
|
16
16
|
end
|
17
17
|
|
18
18
|
def audio?
|
19
|
-
self.class.audio_mime_types.include?
|
19
|
+
self.class.audio_mime_types.include? mime_type
|
20
20
|
end
|
21
21
|
|
22
22
|
def office_document?
|
23
|
-
self.class.office_document_mime_types.include?
|
23
|
+
self.class.office_document_mime_types.include? mime_type
|
24
24
|
end
|
25
25
|
|
26
26
|
def collection?
|
@@ -28,10 +28,10 @@ module Sufia
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def file_format
|
31
|
-
return nil if
|
32
|
-
return
|
33
|
-
return
|
34
|
-
|
31
|
+
return nil if mime_type.blank? && format_label.blank?
|
32
|
+
return mime_type.split('/')[1] + " (" + format_label.join(", ") + ")" unless mime_type.blank? || format_label.blank?
|
33
|
+
return mime_type.split('/')[1] unless mime_type.blank?
|
34
|
+
format_label
|
35
35
|
end
|
36
36
|
|
37
37
|
module ClassMethods
|
@@ -7,15 +7,19 @@ module Sufia
|
|
7
7
|
# query to find generic files created during the time range
|
8
8
|
# @param [DateTime] start_datetime starting date time for range query
|
9
9
|
# @param [DateTime] end_datetime ending date time for range query
|
10
|
-
def find_by_date_created(start_datetime, end_datetime=nil)
|
11
|
-
return [] if start_datetime.blank?
|
12
|
-
|
10
|
+
def find_by_date_created(start_datetime, end_datetime = nil)
|
11
|
+
return [] if start_datetime.blank? # no date just return nothing
|
12
|
+
where(build_date_query(start_datetime, end_datetime))
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_date_query(start_datetime, end_datetime)
|
16
|
+
start_date_str = start_datetime.utc.strftime(date_format)
|
13
17
|
end_date_str = if end_datetime.blank?
|
14
18
|
"*"
|
15
19
|
else
|
16
|
-
end_datetime.utc.strftime(
|
20
|
+
end_datetime.utc.strftime(date_format)
|
17
21
|
end
|
18
|
-
|
22
|
+
"system_create_dtsi:[#{start_date_str} TO #{end_date_str}]"
|
19
23
|
end
|
20
24
|
|
21
25
|
def where_private
|
@@ -1,16 +1,12 @@
|
|
1
1
|
module Sufia
|
2
2
|
module GenericFile
|
3
3
|
module Versions
|
4
|
-
@@count = 0
|
5
4
|
def record_version_committer(user)
|
6
5
|
version = content.latest_version
|
7
6
|
# content datastream not (yet?) present
|
8
7
|
return if version.nil?
|
9
|
-
@@count += 1
|
10
|
-
# raise "Recording #{@@count} #{version.uri} for #{user.user_key}" if @@count == 3
|
11
8
|
VersionCommitter.create(version_id: version.uri, committer_login: user.user_key)
|
12
9
|
end
|
13
|
-
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
@@ -43,7 +43,7 @@ module Sufia::User
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def zotero_token
|
46
|
-
self[:zotero_token].blank? ? nil : Marshal
|
46
|
+
self[:zotero_token].blank? ? nil : Marshal.load(self[:zotero_token])
|
47
47
|
end
|
48
48
|
|
49
49
|
def zotero_token=(value)
|
@@ -51,7 +51,7 @@ module Sufia::User
|
|
51
51
|
# Resetting the token
|
52
52
|
self[:zotero_token] = value
|
53
53
|
else
|
54
|
-
self[:zotero_token] = Marshal
|
54
|
+
self[:zotero_token] = Marshal.dump(value)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -72,14 +72,14 @@ module Sufia::User
|
|
72
72
|
# 1. validation has already flagged the ORCID as invalid
|
73
73
|
# 2. the orcid field is blank
|
74
74
|
# 3. the orcid is already in its normalized form
|
75
|
-
return if
|
76
|
-
bare_orcid = Sufia::OrcidValidator.match(
|
75
|
+
return if errors[:orcid].first.present? || orcid.blank? || orcid.starts_with?('http://orcid.org/')
|
76
|
+
bare_orcid = Sufia::OrcidValidator.match(orcid).string
|
77
77
|
self.orcid = "http://orcid.org/#{bare_orcid}"
|
78
78
|
end
|
79
79
|
|
80
80
|
# Format the json for select2 which requires just an id and a field called text.
|
81
81
|
# If we need an alternate format we should probably look at a json template gem
|
82
|
-
def as_json(
|
82
|
+
def as_json(_opts = nil)
|
83
83
|
{ id: user_key, text: display_name ? "#{display_name} (#{user_key})" : user_key }
|
84
84
|
end
|
85
85
|
|
@@ -89,18 +89,18 @@ module Sufia::User
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def email_address
|
92
|
-
|
92
|
+
email
|
93
93
|
end
|
94
94
|
|
95
95
|
def name
|
96
|
-
|
96
|
+
display_name.titleize || raise
|
97
97
|
rescue
|
98
|
-
|
98
|
+
user_key
|
99
99
|
end
|
100
100
|
|
101
101
|
# Redefine this for more intuitive keys in Redis
|
102
102
|
def to_param
|
103
|
-
#
|
103
|
+
# HACK: because rails doesn't like periods in urls.
|
104
104
|
user_key.gsub(/\./, '-dot-')
|
105
105
|
end
|
106
106
|
|
@@ -116,20 +116,20 @@ module Sufia::User
|
|
116
116
|
end
|
117
117
|
|
118
118
|
# method needed for messaging
|
119
|
-
def mailboxer_email(
|
119
|
+
def mailboxer_email(_obj = nil)
|
120
120
|
nil
|
121
121
|
end
|
122
122
|
|
123
123
|
# The basic groups method, override or will fallback to Sufia::Ldap::User
|
124
124
|
def groups
|
125
|
-
@groups ||=
|
125
|
+
@groups ||= group_list ? group_list.split(";?;") : []
|
126
126
|
end
|
127
127
|
|
128
128
|
def ability
|
129
129
|
@ability ||= ::Ability.new(self)
|
130
130
|
end
|
131
131
|
|
132
|
-
def
|
132
|
+
def all_user_activity(since = DateTime.now.to_i - 8640)
|
133
133
|
events = self.events.reverse.collect { |event| event if event[:timestamp].to_i > since }.compact
|
134
134
|
profile_events = self.profile_events.reverse.collect { |event| event if event[:timestamp].to_i > since }.compact
|
135
135
|
events.concat(profile_events).sort { |a, b| b[:timestamp].to_i <=> a[:timestamp].to_i }
|
@@ -146,7 +146,7 @@ module Sufia::User
|
|
146
146
|
|
147
147
|
# Override this method if you aren't using email/password
|
148
148
|
def audituser
|
149
|
-
User.find_by_user_key(audituser_key) || User.create!(Devise.authentication_keys.first => audituser_key, password: Devise.friendly_token[0,20])
|
149
|
+
User.find_by_user_key(audituser_key) || User.create!(Devise.authentication_keys.first => audituser_key, password: Devise.friendly_token[0, 20])
|
150
150
|
end
|
151
151
|
|
152
152
|
# Override this method if you aren't using email as the userkey
|
@@ -156,7 +156,7 @@ module Sufia::User
|
|
156
156
|
|
157
157
|
# Override this method if you aren't using email/password
|
158
158
|
def batchuser
|
159
|
-
User.find_by_user_key(batchuser_key) || User.create!(Devise.authentication_keys.first => batchuser_key, password: Devise.friendly_token[0,20])
|
159
|
+
User.find_by_user_key(batchuser_key) || User.create!(Devise.authentication_keys.first => batchuser_key, password: Devise.friendly_token[0, 20])
|
160
160
|
end
|
161
161
|
|
162
162
|
# Override this method if you aren't using email as the userkey
|
@@ -170,7 +170,7 @@ module Sufia::User
|
|
170
170
|
|
171
171
|
def recent_users(start_date, end_date = nil)
|
172
172
|
end_date ||= DateTime.now # doing or eq here so that if the user passes nil we still get now
|
173
|
-
|
173
|
+
User.where(created_at: start_date..end_date)
|
174
174
|
end
|
175
175
|
end
|
176
176
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Sufia::UserUsageStats
|
2
|
-
|
3
2
|
def stats
|
4
3
|
@stats ||= UserStat.where(user_id: id).order(date: :asc)
|
5
4
|
end
|
@@ -11,5 +10,4 @@ module Sufia::UserUsageStats
|
|
11
10
|
def total_file_downloads
|
12
11
|
stats.reduce(0) { |total, stat| total + stat.file_downloads }
|
13
12
|
end
|
14
|
-
|
15
13
|
end
|
@@ -5,13 +5,13 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
5
5
|
t.root(path: "fits",
|
6
6
|
xmlns: "http://hul.harvard.edu/ois/xml/ns/fits/fits_output",
|
7
7
|
schema: "http://hul.harvard.edu/ois/xml/xsd/fits/fits_output.xsd")
|
8
|
-
t.identification
|
9
|
-
t.identity
|
10
|
-
t.format_label(path: {attribute: "format"})
|
11
|
-
t.mime_type(path: {attribute: "mimetype"})
|
12
|
-
|
13
|
-
|
14
|
-
t.fileinfo
|
8
|
+
t.identification do
|
9
|
+
t.identity do
|
10
|
+
t.format_label(path: { attribute: "format" })
|
11
|
+
t.mime_type(path: { attribute: "mimetype" })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
t.fileinfo do
|
15
15
|
t.file_size(path: "size")
|
16
16
|
t.last_modified(path: "lastmodified")
|
17
17
|
t.filename(path: "filename")
|
@@ -19,14 +19,14 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
19
19
|
t.rights_basis(path: "rightsBasis")
|
20
20
|
t.copyright_basis(path: "copyrightBasis")
|
21
21
|
t.copyright_note(path: "copyrightNote")
|
22
|
-
|
23
|
-
t.filestatus
|
22
|
+
end
|
23
|
+
t.filestatus do
|
24
24
|
t.well_formed(path: "well-formed")
|
25
25
|
t.valid(path: "valid")
|
26
26
|
t.status_message(path: "message")
|
27
|
-
|
28
|
-
t.metadata
|
29
|
-
t.document
|
27
|
+
end
|
28
|
+
t.metadata do
|
29
|
+
t.document do
|
30
30
|
t.file_title(path: "title")
|
31
31
|
t.file_author(path: "author")
|
32
32
|
t.file_language(path: "language")
|
@@ -37,8 +37,8 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
37
37
|
t.line_count(path: "lineCount")
|
38
38
|
t.table_count(path: "tableCount")
|
39
39
|
t.graphics_count(path: "graphicsCount")
|
40
|
-
|
41
|
-
t.image
|
40
|
+
end
|
41
|
+
t.image do
|
42
42
|
t.byte_order(path: "byteOrder")
|
43
43
|
t.compression(path: "compressionScheme")
|
44
44
|
t.width(path: "imageWidth")
|
@@ -55,28 +55,28 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
55
55
|
t.gps_timestamp(path: "gpsTimeStamp")
|
56
56
|
t.latitude(path: "gpsDestLatitude")
|
57
57
|
t.longitude(path: "gpsDestLongitude")
|
58
|
-
|
59
|
-
t.text
|
58
|
+
end
|
59
|
+
t.text do
|
60
60
|
t.character_set(path: "charset")
|
61
61
|
t.markup_basis(path: "markupBasis")
|
62
62
|
t.markup_language(path: "markupLanguage")
|
63
|
-
|
64
|
-
t.audio
|
63
|
+
end
|
64
|
+
t.audio do
|
65
65
|
t.duration(path: "duration")
|
66
66
|
t.bit_depth(path: "bitDepth")
|
67
67
|
t.sample_rate(path: "sampleRate")
|
68
68
|
t.channels(path: "channels")
|
69
69
|
t.data_format(path: "dataFormatType")
|
70
70
|
t.offset(path: "offset")
|
71
|
-
|
72
|
-
t.video
|
71
|
+
end
|
72
|
+
t.video do
|
73
73
|
t.width(path: "imageWidth")
|
74
74
|
t.height(path: "imageHeight")
|
75
75
|
t.duration(path: "duration")
|
76
76
|
t.sample_rate(path: "sampleRate")
|
77
77
|
t.frame_rate(path: "frameRate")
|
78
|
-
|
79
|
-
|
78
|
+
end
|
79
|
+
end
|
80
80
|
t.format_label(proxy: [:identification, :identity, :format_label])
|
81
81
|
t.mime_type(proxy: [:identification, :identity, :mime_type])
|
82
82
|
t.file_size(proxy: [:fileinfo, :file_size])
|
@@ -102,7 +102,7 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
102
102
|
t.byte_order(proxy: [:metadata, :image, :byte_order])
|
103
103
|
t.compression(proxy: [:metadata, :image, :compression])
|
104
104
|
t.width(proxy: [:metadata, :image, :width])
|
105
|
-
t.video_width(
|
105
|
+
t.video_width(proxy: [:metadata, :video, :width])
|
106
106
|
t.height(proxy: [:metadata, :image, :height])
|
107
107
|
t.video_height(proxy: [:metadata, :video, :height])
|
108
108
|
t.color_space(proxy: [:metadata, :image, :color_space])
|
@@ -139,9 +139,9 @@ class FitsDatastream < ActiveFedora::OmDatastream
|
|
139
139
|
"http://hul.harvard.edu/ois/xml/ns/fits/fits_output
|
140
140
|
http://hul.harvard.edu/ois/xml/xsd/fits/fits_output.xsd",
|
141
141
|
version: "0.6.0",
|
142
|
-
timestamp: "1/25/12 11:04 AM")
|
142
|
+
timestamp: "1/25/12 11:04 AM") do
|
143
143
|
xml.identification { xml.identity(toolname: 'FITS') }
|
144
|
-
|
144
|
+
end
|
145
145
|
end
|
146
146
|
builder.doc
|
147
147
|
end
|
data/app/models/domain_term.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class DomainTerm < ActiveRecord::Base
|
2
|
-
|
3
|
-
|
4
|
-
has_and_belongs_to_many :local_authorities, -> {uniq}
|
2
|
+
# TODO: we should add an index on this join table and remove the uniq query
|
3
|
+
has_and_belongs_to_many :local_authorities, -> { uniq }
|
5
4
|
end
|
data/app/models/featured_work.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
class FeaturedWork < ActiveRecord::Base
|
2
2
|
FEATURE_LIMIT = 5
|
3
3
|
validate :count_within_limit, on: :create
|
4
|
-
validates :order, inclusion: { in:
|
4
|
+
validates :order, inclusion: { in: proc { 0..FEATURE_LIMIT } }
|
5
5
|
|
6
6
|
default_scope { order(:order) }
|
7
7
|
|
8
8
|
def count_within_limit
|
9
|
-
|
10
|
-
|
11
|
-
end
|
9
|
+
return if FeaturedWork.can_create_another?
|
10
|
+
errors.add(:base, "Limited to #{FEATURE_LIMIT} featured works.")
|
12
11
|
end
|
13
12
|
|
14
13
|
attr_accessor :generic_file_solr_document
|
@@ -19,4 +18,3 @@ class FeaturedWork < ActiveRecord::Base
|
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
22
|
-
|