Skip to content

Commit

Permalink
Merge pull request #33 from pulibrary/collections
Browse files Browse the repository at this point in the history
Implement Collections
  • Loading branch information
escowles committed Jul 31, 2017
2 parents 5a0400b + 73f3f40 commit 9f5129b
Show file tree
Hide file tree
Showing 33 changed files with 379 additions and 70 deletions.
12 changes: 11 additions & 1 deletion app/change_set_persisters/plum_change_set_persister.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def before_save(change_set:)

def after_save(change_set:, updated_resource:); end

def before_delete(change_set:); end
def before_delete(change_set:)
clean_up_collection_associations(change_set: change_set) if change_set.resource.is_a?(Collection)
end

def apply_remote_metadata(change_set:)
return unless change_set.respond_to?(:source_metadata_identifier)
Expand All @@ -57,6 +59,14 @@ def apply_remote_metadata(change_set:)
end
end

def clean_up_collection_associations(change_set:)
resources = query_service.find_inverse_references_by(resource: change_set.resource, property: :member_of_collection_ids)
resources.each do |resource|
resource.member_of_collection_ids -= [change_set.id]
persister.save(resource: resource)
end
end

def create_files(change_set:)
appender = FileAppender.new(storage_adapter: storage_adapter, persister: persister, files: files(change_set: change_set))
appender.append_to(change_set.resource)
Expand Down
13 changes: 13 additions & 0 deletions app/change_sets/collection_change_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true
class CollectionChangeSet < Valkyrie::ChangeSet
delegate :human_readable_type, to: :model
property :title, multiple: false, required: true
property :slug, multiple: false, required: true
property :description, multiple: false, required: false
property :visibility, multiple: false, required: false
validates :title, :slug, presence: true

def primary_terms
[:title, :slug, :description]
end
end
4 changes: 3 additions & 1 deletion app/change_sets/scanned_resource_change_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class ScannedResourceChangeSet < Valkyrie::ChangeSet
property :member_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)
property :thumbnail_id, multiple: false, required: false, type: Valkyrie::Types::ID
property :start_canvas, multiple: false, type: Valkyrie::Types::ID
property :member_of_collection_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)

# Virtual Attributes
property :refresh_remote_metadata, virtual: true, multiple: false
Expand All @@ -38,7 +39,8 @@ def primary_terms
:holding_location,
:pdf_type,
:portion_note,
:nav_date
:nav_date,
:member_of_collection_ids
]
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/catalog_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def self.search_config

config.index.title_field = 'title_ssim'
config.index.display_type_field = "internal_resource_ssim"
config.add_facet_field 'title_ssim', label: 'Title'
config.add_facet_field 'member_of_collection_titles_ssim', label: 'Collections'
config.add_facet_field 'internal_resource_ssim', label: 'Type of Work'
config.add_facet_fields_to_solr_request!

config.add_search_field 'all_fields', label: 'All Fields'
Expand Down
10 changes: 10 additions & 0 deletions app/controllers/collections_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true
class CollectionsController < ApplicationController
include Valhalla::ResourceController
self.change_set_class = DynamicChangeSet
self.resource_class = Collection
self.change_set_persister = PlumChangeSetPersister.new(
metadata_adapter: Valkyrie::MetadataAdapter.find(:indexing_persister),
storage_adapter: Valkyrie.config.storage_adapter
)
end
5 changes: 5 additions & 0 deletions app/controllers/scanned_resources_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ class ScannedResourcesController < ApplicationController
metadata_adapter: Valkyrie::MetadataAdapter.find(:indexing_persister),
storage_adapter: Valkyrie.config.storage_adapter
)
before_action :load_collections, only: [:new, :edit]

def load_collections
@collections = query_service.find_all_of_model(model: Collection).map(&:decorate)
end

def browse_everything_files
change_set_persister.buffer_into_index do |buffered_changeset_persister|
Expand Down
10 changes: 10 additions & 0 deletions app/decorators/collection_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true
class CollectionDecorator < Valkyrie::ResourceDecorator
def title
Array(super).first
end

def manageable_files?
false
end
end
20 changes: 19 additions & 1 deletion app/decorators/scanned_resource_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
# frozen_string_literal: true
class ScannedResourceDecorator < Valkyrie::ResourceDecorator
self.display_attributes = [:author, :internal_resource, :created_at, :updated_at]
self.display_attributes = [:author, :internal_resource, :created_at, :updated_at, :member_of_collections]
delegate :query_service, to: :metadata_adapter

def member_of_collections
@member_of_collections ||=
begin
member_of_collection_ids.map do |id|
query_service.find_by(id: id).decorate
end.map(&:title)
end
end

def member_of_collection_ids
super || []
end

def metadata_adapter
Valkyrie.config.metadata_adapter
end
end
2 changes: 1 addition & 1 deletion app/decorators/valkyrie/resource_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def updated_at
end

def header
title.to_sentence
Array(title).to_sentence
end

def manageable_files?
Expand Down
27 changes: 27 additions & 0 deletions app/indexers/collection_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true
class CollectionIndexer
delegate :query_service, to: :metadata_adapter
attr_reader :resource
def initialize(resource:)
@resource = resource
end

def to_solr
return {} unless resource.respond_to?(:member_of_collection_ids)
{
"member_of_collection_titles_ssim" => collections.map(&:title).to_a
}
end

def collections
return [] if resource.member_of_collection_ids.blank?
@collections ||=
begin
query_service.find_references_by(resource: resource, property: :member_of_collection_ids).map(&:decorate)
end
end

def metadata_adapter
Valkyrie.config.metadata_adapter
end
end
23 changes: 23 additions & 0 deletions app/indexers/composite_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true
class CompositeIndexer
attr_reader :indexers
def initialize(*indexers)
@indexers = indexers
end

def new(resource:)
Instance.new(indexers, resource: resource)
end

class Instance
attr_reader :indexers, :resource
def initialize(indexers, resource:)
@resource = resource
@indexers = indexers.map { |i| i.new(resource: resource) }
end

def to_solr
indexers.map(&:to_solr).inject({}, &:merge)
end
end
end
9 changes: 9 additions & 0 deletions app/models/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true
class Collection < Valhalla::Resource
include Valkyrie::Resource::AccessControls
attribute :id, Valkyrie::Types::ID.optional
attribute :title, Valkyrie::Types::Set
attribute :slug, Valkyrie::Types::Set
attribute :description, Valkyrie::Types::Set
attribute :visibility, Valkyrie::Types::Set
end
1 change: 1 addition & 0 deletions app/models/scanned_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ScannedResource < Valhalla::Resource
attribute :member_ids, Valkyrie::Types::Array
attribute :viewing_hint
attribute :viewing_direction
attribute :member_of_collection_ids

def to_s
"#{human_readable_type}: #{title.to_sentence}"
Expand Down
2 changes: 1 addition & 1 deletion app/models/search_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def filter_models(solr_parameters)
end

def models_to_solr_clause
[ScannedResource].join(",")
[ScannedResource, Collection].join(",")
end

def add_access_controls_to_solr_params(*args)
Expand Down
2 changes: 1 addition & 1 deletion app/views/catalog/_home_text.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
types: [] } %>
<%= render partial: 'catalog/work_types', locals: { label: 'Collections',
types: [] } %>
types: [Collection] } %>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= f.input :member_of_collection_ids, collection: @collections, label_method: :title, value_method: :id, input_html: { multiple: f.object.multiple?(key) }, include_blank: true %>
39 changes: 1 addition & 38 deletions app/views/shared/_add_content.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,10 @@
<%= render 'shared/add_works' %>
</li>
<% end %>
</ul>
</div>
<% end %>
<% if false %>
<% include_works_link ||= can_ever_create_works? %>
<% include_collections_link ||= can?(:create, ::Collection) %>
<% include_roles_link ||= can?(:create, ::Role) %>
<% if include_works_link || include_collections_link || include_roles_link %>
<div class="btn-group add-content">
<%= link_to '#', id: "add-content", class: "btn btn-primary dropdown-toggle", data: { toggle: "dropdown"} do %>
<span class="glyphicon glyphicon-plus"></span><span class="visuallyhidden">Add</span>
<% end %>
<ul class="dropdown-menu quick-create">
<% if include_works_link %>
<li>
<%= render 'shared/add_works' %>
</li>
<% end %>
<% if include_collections_link %>
<% if can?(:create, ::Collection) %>
<li class="divider"></li>
<li><%= link_to 'Add a Collection', main_app.new_collection_path, class: 'menu-heading new-collection', role: 'menuitem' %></li>
<% end %>
<% if include_roles_link %>
<li class="divider"></li>
<li><%= link_to 'Manage Roles', role_management.roles_path, class: 'menu-heading manage-roles', role: 'menuitem' %></li>
<li><%= link_to 'Workflow Roles', hyrax.admin_workflow_roles_path, class: 'menu-heading manage-workflow-roles', role: 'menuitem' %></li>
<% end %>
<% if can?(:create, Vocabulary) || can?(:create, EphemeraProject) %>
<li class="divider"></li>
<% end %>
<% if can?(:create, EphemeraProject) %>
<li><%= link_to 'Manage Ephemera Projects', main_app.ephemera_projects_path, class: 'menu-heading manage-ephemera-projects', role: 'menuitem' %></li>
<% end %>
<% if can?(:create, Vocabulary) %>
<li><%= link_to 'Manage Vocabularies', main_app.vocabularies_path, class: 'menu-heading manage-vocabularies', role: 'menuitem' %></li>
<% end %>
<% if can?(:create, AuthToken) %>
<li class="divider"></li>
<li><%= link_to 'Manage Auth Tokens', main_app.auth_tokens_path, class: 'menu-heading manage-auth-tokens', role: 'menuitem' %></li>
<% end %>
</ul>
</div>
<% end %>
<% end %>
22 changes: 0 additions & 22 deletions app/views/shared/_my_actions.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,7 @@
<span class="caret"></span>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<% if false %>
<% include_works_link ||= can_ever_create_works? %>
<% include_collections_link ||= can?(:create, Collection) %>
<% if include_works_link %>
<li><%= link_to 'My Works', search_path_for_my_works, class: 'my-works', role: 'menuitem' %></li>
<% end %>
<% if include_collections_link %>
<li><%= link_to 'My Collections', search_path_for_my_collections, class: 'my-collections', role: 'menuitem' %></li>
<% end %>
<% if can? :discover, Hydra::AccessControls::Embargo %>
<li><%= link_to 'Embargos', main_app.embargoes_path, role: 'menuitem' %></li>
<% end %>
<% if can? :discover, Hydra::AccessControls::Lease %>
<li><%= link_to 'Leases', main_app.leases_path, role: 'menuitem' %></li>
<% end %>
<% if include_works_link || include_collections_link %>
<li class="divider"></li>
<% end %>
<% end %>
<li>
<%# <%= link_to 'Log Out', main_app.destroy_user_session_path, class: 'log-out', role: 'menuitem' %>
<%= link_to 'Log Out', main_app.destroy_user_session_path, class: 'log-out', role: 'menuitem' %>
</li>
</ul>
Expand Down
1 change: 0 additions & 1 deletion app/views/shared/_site_actions.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
<%= render 'shared/add_content' %>
<%= render 'shared/my_actions' %>
<% else %>
<%# <%= link_to 'Log In', main_app.user_cas_omniauth_authorize_path, class: 'btn btn-primary login', role: 'menuitem' %>
<%= link_to 'Log In', main_app.new_user_session_path, class: 'btn btn-primary login', role: 'menuitem' %>
<% end %>
5 changes: 4 additions & 1 deletion config/initializers/valkyrie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
Valkyrie::MetadataAdapter.register(
Valkyrie::Persistence::Solr::MetadataAdapter.new(
connection: Blacklight.default_index.connection,
resource_indexer: Valkyrie::Indexers::AccessControlsIndexer
resource_indexer: CompositeIndexer.new(
Valkyrie::Indexers::AccessControlsIndexer,
CollectionIndexer
)
),
:index_solr
)
Expand Down
2 changes: 2 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ en:
label: "Date Uploaded"
updated_at:
label: "Date Modified"
member_of_collections:
label: "Collections"
search:
form:
q:
Expand Down
1 change: 1 addition & 0 deletions config/locales/simple_form.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ en:
pdf_type: "PDF Type"
portion_note: "Portion Note"
nav_date: "Navigation Date"
member_of_collection_ids: "Collections"
required:
html: '<span class="label label-info required-tag">required</span>'
helpers:
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
end
end

resources :collections

get '/catalog/parent/:parent_id/:id', to: 'catalog#show', as: :parent_solr_document

mount BrowseEverything::Engine => '/browse'
Expand Down
15 changes: 15 additions & 0 deletions spec/change_set_persisters/plum_change_set_persister_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,19 @@
expect(original_file).to respond_to(:read)
end
end

describe "collection interactions" do
context "when a collection is deleted" do
it "cleans up associations from all its members" do
collection = FactoryGirl.create_for_repository(:collection)
resource = FactoryGirl.create_for_repository(:scanned_resource, member_of_collection_ids: collection.id)
change_set = CollectionChangeSet.new(collection)

change_set_persister.delete(change_set: change_set)
reloaded = query_service.find_by(id: resource.id)

expect(reloaded.member_of_collection_ids).to eq []
end
end
end
end
Loading

0 comments on commit 9f5129b

Please sign in to comment.