Skip to content

Commit

Permalink
Merge pull request #654 from samvera-labs/github-647
Browse files Browse the repository at this point in the history
Adding configuration for resource_klass resolver
  • Loading branch information
tpendragon committed Jan 30, 2019
2 parents 1c8458c + 3cbccd3 commit 8879693
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 4 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ The initializer also registers three `Valkyrie::StorageAdapter` instances for st
* `:memory` which stores files in an in-memory cache (again, not persistent, so this is only appropriate for
testing)

### Sample configuration with custom `Valkyrie.config.resource_class_resolver`:

```
require 'valkyrie'
Rails.application.config.to_prepare do
Valkyrie.config.resource_class_resolver = lambda do |resource_klass_name|
# Do complicated lookup based on the string
end
end
```

### Sample configuration: `config/valkyrie.yml`:

A sample configuration file that configures your application to use different adapters:
Expand Down
28 changes: 27 additions & 1 deletion lib/valkyrie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,39 @@ def storage_adapter
Valkyrie::StorageAdapter.find(super.to_sym)
end

# @api public
#
# The returned anonymous method (e.g. responds to #call) has a signature of
# an unamed parameter that is a string. Calling the anonymous method should
# return a Valkyrie::Resource from which Valkyrie will map the persisted
# data into.
#
# @return [#call] with method signature of 1
#
# @see #default_resource_class_resolver for full interface
def resource_class_resolver
super
end

# @!attribute [w] resource_class_resolver=
# The setter for #resource_class_resolver; see it's implementation

private

def defaults
{
standardize_query_result: false
standardize_query_result: false,
resource_class_resolver: method(:default_resource_class_resolver)
}
end

# String constantize is a "by convention" factory. This works, but assumes
# the ruby class once used to persist is the model used to now reify.
#
# @param [String] class_name
def default_resource_class_resolver(class_name)
class_name.constantize
end
end

module_function :config, :logger, :logger=, :config_root_path, :environment, :warn_about_standard_queries!, :config_file, :config_hash
Expand Down
2 changes: 1 addition & 1 deletion lib/valkyrie/persistence/postgres/orm_converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def lock_token_warning
# Retrieve the Class used to construct the Valkyrie Resource
# @return [Class]
def resource_klass
internal_resource.constantize
Valkyrie.config.resource_class_resolver.call(internal_resource)
end

# Access the String for the Valkyrie Resource type within the attributes
Expand Down
2 changes: 1 addition & 1 deletion lib/valkyrie/persistence/solr/orm_converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def resource
# Access the Class for the Valkyrie Resource
# @return [Class]
def resource_klass
internal_resource.constantize
Valkyrie.config.resource_class_resolver.call(internal_resource)
end

# Access the String specifying the Valkyrie Resource type in the Solr Document
Expand Down
3 changes: 2 additions & 1 deletion lib/valkyrie/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ module Params
# Used for casting {Valkyrie::Resources} if possible.
Anything = Valkyrie::Types::Any.constructor do |value|
if value.respond_to?(:fetch) && value.fetch(:internal_resource, nil)
value.fetch(:internal_resource).constantize.new(value)
resource_klass = Valkyrie.config.resource_class_resolver.call(value.fetch(:internal_resource))
resource_klass.new(value)
else
value
end
Expand Down
25 changes: 25 additions & 0 deletions spec/valkyrie_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,29 @@
expect(Rails).to have_received(:root).exactly(8).times
end
end
describe ".config" do
describe '.resource_class_resolver' do
subject(:resolver) { described_class.config.resource_class_resolver }
it { is_expected.to respond_to(:call).with(1).argument }
context 'when called' do
it 'will by default constantize the given string' do
expect(resolver.call('Valkyrie')).to eq(described_class)
end
end
context 'when configured' do
around do |example|
original = described_class.config.resource_class_resolver
example.run
described_class.config.resource_class_resolver = original
end
it 'will use the configured lambda' do
# Yes. This does not conform to the expected output, but
# I'm looking to demonstrate how this works
new_resolver = ->(string) { string.to_sym }
described_class.config.resource_class_resolver = new_resolver
expect(described_class.config.resource_class_resolver.call('hello')).to eq(:hello)
end
end
end
end
end

0 comments on commit 8879693

Please sign in to comment.