Skip to content

Commit

Permalink
Allow property to delegate to a datastream. Ref #736
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoyne committed Apr 2, 2015
1 parent 8e3cad1 commit 9bc5537
Show file tree
Hide file tree
Showing 21 changed files with 164 additions and 57 deletions.
38 changes: 28 additions & 10 deletions lib/active_fedora/attributes.rb
@@ -1,7 +1,10 @@
require 'active_model/forbidden_attributes_protection'
require 'deprecation'
module ActiveFedora
module Attributes
extend ActiveSupport::Concern
extend Deprecation
self.deprecation_horizon = 'ActiveFedora 10.0'
include ActiveModel::Dirty
include ActiveModel::ForbiddenAttributesProtection

Expand Down Expand Up @@ -145,15 +148,8 @@ def delegated_attributes= val
end

def has_attributes(*fields, &block)
options = fields.pop
datastream = options.delete(:datastream).to_s
raise ArgumentError, "You must provide a datastream to has_attributes" if datastream.blank?
define_attribute_methods fields
fields.each do |f|
create_attribute_reader(f, datastream, options)
create_attribute_setter(f, datastream, options)
add_attribute_indexing_config(f, &block) if block_given?
end
Deprecation.warn(Attributes, "has_attributes is deprecated and will be removed in ActiveFedora 10.0. Use property instead")
define_delegated_accessor(*fields, &block)
end

# Reveal if the attribute has been declared unique
Expand All @@ -172,6 +168,18 @@ def multiple?(field)
end

def property name, properties={}, &block
if properties.key?(:predicate)
define_active_triple_accessor(name, properties, &block)
elsif properties.key?(:datastream)
define_delegated_accessor(name, properties.merge(multiple: true), &block)
else
raise "You must provide `:datastream' or `:predicate' options to property"
end
end

private

def define_active_triple_accessor(name, properties, &block)
warn_duplicate_predicates name, properties
properties = { multiple: true }.merge(properties)
find_or_create_defined_attribute(name, nil, properties)
Expand All @@ -182,7 +190,17 @@ def property name, properties={}, &block
add_attribute_indexing_config(name, &block) if block_given?
end

private
def define_delegated_accessor(*fields, &block)
options = fields.pop
datastream = options.delete(:datastream).to_s
raise ArgumentError, "You must provide a datastream to has_attributes" if datastream.blank?
define_attribute_methods fields
fields.each do |f|
create_attribute_reader(f, datastream, options)
create_attribute_setter(f, datastream, options)
add_attribute_indexing_config(f, &block) if block_given?
end
end

def add_attribute_indexing_config(name, &block)
# TODO the hash can be initalized to return on of these
Expand Down
13 changes: 9 additions & 4 deletions spec/integration/attributes_spec.rb
@@ -1,5 +1,6 @@
require 'spec_helper'


describe "delegating attributes" do
before :all do
class PropertiesDatastream < ActiveFedora::OmDatastream
Expand All @@ -13,14 +14,18 @@ class TitledObject < ActiveFedora::Base
has_metadata 'foo', type: ActiveFedora::SimpleDatastream do |m|
m.field "title", :string
end
has_attributes :title, datastream: 'foo', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :title, datastream: 'foo', multiple: false
end
end
class RdfObject < ActiveFedora::Base
contains 'foo', class_name: 'PropertiesDatastream'
has_attributes :depositor, datastream: :foo, multiple: false do |index|
index.as :stored_searchable
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :depositor, datastream: :foo, multiple: false do |index|
index.as :stored_searchable
end
has_attributes :wrangler, datastream: :foo, multiple: true
end
has_attributes :wrangler, datastream: :foo, multiple: true
property :resource_type, predicate: ::RDF::DC.type do |index|
index.as :stored_searchable, :facetable
end
Expand Down
4 changes: 3 additions & 1 deletion spec/integration/field_to_solr_name_spec.rb
Expand Up @@ -16,7 +16,9 @@ class MyMetadata < ActiveFedora::NtriplesRDFDatastream
end
end
has_metadata 'descMetadata', type: MyMetadata
has_attributes :title, :date_uploaded, datastream: 'descMetadata'
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :title, :date_uploaded, datastream: 'descMetadata'
end
end
end

Expand Down
8 changes: 6 additions & 2 deletions spec/integration/has_and_belongs_to_many_associations_spec.rb
Expand Up @@ -334,15 +334,19 @@ class Item < ActiveFedora::Base
has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
m.field "title", :string
end
has_attributes :title, datastream: 'foo'
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :title, datastream: 'foo'
end
end

class Component < ActiveFedora::Base
has_and_belongs_to_many :items, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
m.field "description", :string
end
has_attributes :description, datastream: 'foo'
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :description, datastream: 'foo'
end
end
end

Expand Down
8 changes: 6 additions & 2 deletions spec/integration/has_many_associations_spec.rb
Expand Up @@ -276,14 +276,18 @@ class Item < ActiveFedora::Base
has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
m.field "title", :string
end
has_attributes :title, datastream: 'foo'
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :title, datastream: 'foo'
end
end
class Component < ActiveFedora::Base
belongs_to :item, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
m.field "description", :string
end
has_attributes :description, datastream: 'foo'
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :description, datastream: 'foo'
end
end
end

Expand Down
10 changes: 7 additions & 3 deletions spec/integration/json_serialization_spec.rb
Expand Up @@ -12,8 +12,10 @@ class Foo < ActiveFedora::Base
m.field "foo", :text
m.field "bar", :text
end
has_attributes :foo, datastream: 'descMetadata', multiple: true
has_attributes :bar, datastream: 'descMetadata', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :foo, datastream: 'descMetadata', multiple: true
has_attributes :bar, datastream: 'descMetadata', multiple: false
end
property :title, predicate: ::RDF::DC.title
end
end
Expand Down Expand Up @@ -55,7 +57,9 @@ def serialization_format

class DummyAsset < ActiveFedora::Base
has_metadata 'descMetadata', type: DummyResource
has_attributes :relation, datastream: 'descMetadata', at: [:license, :relation], multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :relation, datastream: 'descMetadata', at: [:license, :relation], multiple: false
end
end
end

Expand Down
4 changes: 3 additions & 1 deletion spec/integration/nested_attribute_spec.rb
Expand Up @@ -8,7 +8,9 @@ class Bar < ActiveFedora::Base
m.field "uno", :string
m.field "dos", :string
end
has_attributes :uno, :dos, datastream: 'someData', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :uno, :dos, datastream: 'someData', multiple: false
end
end

# base Car class, used in test for association updates and :allow_destroy flag
Expand Down
10 changes: 7 additions & 3 deletions spec/integration/ntriples_datastream_spec.rb
Expand Up @@ -28,8 +28,10 @@ class MyDatastream < ActiveFedora::NtriplesRDFDatastream

class RdfTest < ActiveFedora::Base
has_metadata 'rdf', type: MyDatastream
has_attributes :based_near, :related_url, :part, :date_uploaded, datastream: 'rdf', multiple: true
has_attributes :title, :filesize, datastream: 'rdf', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :based_near, :related_url, :part, :date_uploaded, datastream: 'rdf', multiple: true
has_attributes :title, :filesize, datastream: 'rdf', multiple: false
end
end
@subject = RdfTest.new
end
Expand Down Expand Up @@ -218,7 +220,9 @@ class TitleDatastream < ActiveFedora::NtriplesRDFDatastream
end
class Foobar < ActiveFedora::Base
has_metadata 'rdf', type: TitleDatastream
has_attributes :title, datastream: 'rdf', multiple: true
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :title, datastream: 'rdf', multiple: true
end
end
@subject = Foobar.new
@subject.title = ["title1", "title2", "title3"]
Expand Down
4 changes: 3 additions & 1 deletion spec/integration/persistence_spec.rb
Expand Up @@ -6,7 +6,9 @@ class MockAFBaseRelationship < ActiveFedora::Base
has_metadata :type=>ActiveFedora::SimpleDatastream, :name=>"foo" do |m|
m.field "name", :string
end
has_attributes :name, datastream: 'foo', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :name, datastream: 'foo', multiple: false
end
validates :name, presence: true
end
end
Expand Down
4 changes: 3 additions & 1 deletion spec/integration/relation_delegation_spec.rb
Expand Up @@ -11,7 +11,9 @@ class Basic < ActiveFedora::Base
m.field "baz", :string
end

has_attributes :foo, :bar, :baz, datastream: 'properties', multiple: true
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :foo, :bar, :baz, datastream: 'properties', multiple: true
end

def to_solr(doc = {})
doc = super
Expand Down
4 changes: 3 additions & 1 deletion spec/integration/scoped_query_spec.rb
Expand Up @@ -11,7 +11,9 @@ class Basic < ActiveFedora::Base
m.field "baz", :string
end

has_attributes :foo, :bar, :baz, datastream: 'properties', multiple: true
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :foo, :bar, :baz, datastream: 'properties', multiple: true
end

def to_solr(doc = {})
doc = super
Expand Down
6 changes: 4 additions & 2 deletions spec/integration/solr_instance_loader_spec.rb
Expand Up @@ -7,8 +7,10 @@ class Foo < ActiveFedora::Base
m.field "foo", :text
m.field "bar", :text
end
has_attributes :foo, datastream: 'descMetadata', multiple: true
has_attributes :bar, datastream: 'descMetadata', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :foo, datastream: 'descMetadata', multiple: true
has_attributes :bar, datastream: 'descMetadata', multiple: false
end
property :title, predicate: ::RDF::DC.title, multiple: false
property :description, predicate: ::RDF::DC.description
belongs_to :another, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'Foo'
Expand Down
64 changes: 52 additions & 12 deletions spec/unit/attributes_spec.rb
Expand Up @@ -33,6 +33,34 @@ def self.xml_template
Object.send(:remove_const, :BarStream2)
end

describe "#property" do
context "with an xml property" do
before do
class BarHistory4 < ActiveFedora::Base
has_metadata type: BarStream2, name: "xmlish"
property :cow, datastream: 'xmlish'
end
end
after do
Object.send(:remove_const, :BarHistory4)
end

let(:obj) { BarHistory4.new }

before { obj.cow = ['one', 'two'] }
describe "the object accessor" do
subject { obj.cow }
it { is_expected.to eq ['one', 'two'] }
end

describe "the datastream accessor" do
subject { obj.xmlish.cow }
it { is_expected.to eq ['one', 'two'] }
end

end
end

describe "first level delegation" do
before :all do
class BarHistory2 < ActiveFedora::Base
Expand All @@ -50,12 +78,14 @@ class BarHistory2 < ActiveFedora::Base
end

has_metadata :type=>BarStream2, :name=>"xmlish"
has_attributes :cow, datastream: 'xmlish' # for testing the default value of multiple
has_attributes :fubar, datastream: 'withText', multiple: true # test alternate datastream
has_attributes :pig, datastream: 'xmlish', multiple: false
has_attributes :horse, datastream: 'xmlish', multiple: true
has_attributes :duck, datastream: 'xmlish', :at=>[:waterfowl, :ducks, :duck], multiple: true
has_attributes :animal_id, datastream: 'someData', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :cow, datastream: 'xmlish' # for testing the default value of multiple
has_attributes :fubar, datastream: 'withText', multiple: true # test alternate datastream
has_attributes :pig, datastream: 'xmlish', multiple: false
has_attributes :horse, datastream: 'xmlish', multiple: true
has_attributes :duck, datastream: 'xmlish', :at=>[:waterfowl, :ducks, :duck], multiple: true
has_attributes :animal_id, datastream: 'someData', multiple: false
end

property :goose, predicate: ::RDF::URI.new('http://example.com#hasGoose')

Expand Down Expand Up @@ -253,7 +283,9 @@ class BarHistory3 < BarHistory2
before :all do
class BarHistory2 < ActiveFedora::Base
has_metadata 'xmlish', :type=>BarStream2
has_attributes :donkey, :cow, datastream: 'xmlish', multiple: true
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :donkey, :cow, datastream: 'xmlish', multiple: true
end
end
class BarHistory3 < BarHistory2
end
Expand Down Expand Up @@ -287,8 +319,10 @@ class BarRdfDatastream < ActiveFedora::NtriplesRDFDatastream
end
class BarHistory4 < ActiveFedora::Base
has_metadata 'rdfish', :type=>BarRdfDatastream
has_attributes :title, datastream: 'rdfish', multiple: true
has_attributes :description, datastream: 'rdfish', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :title, datastream: 'rdfish', multiple: true
has_attributes :description, datastream: 'rdfish', multiple: false
end
end
end

Expand Down Expand Up @@ -330,7 +364,9 @@ class BarHistory4 < ActiveFedora::Base

describe "has_attributes" do
it "should raise an error" do
expect {subject.has_attributes :title, :description, multiple: true}.to raise_error
Deprecation.silence(ActiveFedora::Attributes) do
expect {subject.has_attributes :title, :description, multiple: true}.to raise_error
end
end
end
end
Expand All @@ -339,7 +375,9 @@ class BarHistory4 < ActiveFedora::Base
context "when an unknown datastream is specified" do
before :all do
class BarHistory4 < ActiveFedora::Base
has_attributes :description, datastream: 'rdfish', multiple: true
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :description, datastream: 'rdfish', multiple: true
end
end
end

Expand Down Expand Up @@ -372,7 +410,9 @@ class BarRdfDatastream < ActiveFedora::NtriplesRDFDatastream
end
class BarHistory4 < ActiveFedora::Base
has_metadata 'rdfish', :type=>BarRdfDatastream
has_attributes :description, datastream: :rdfish
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :description, datastream: :rdfish
end
end
end

Expand Down
6 changes: 4 additions & 2 deletions spec/unit/base_active_model_spec.rb
Expand Up @@ -28,8 +28,10 @@ class BarHistory < ActiveFedora::Base
end

has_metadata :type=>BarStream, :name=>"xmlish"
has_attributes :fubar, datastream: 'withText', multiple: false
has_attributes :duck, datastream: 'xmlish', multiple: false
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :fubar, datastream: 'withText', multiple: false
has_attributes :duck, datastream: 'xmlish', multiple: false
end
end
before :each do
@n = BarHistory.new()
Expand Down
6 changes: 4 additions & 2 deletions spec/unit/base_spec.rb
Expand Up @@ -70,8 +70,10 @@ class FooHistory < ActiveFedora::Base
has_metadata "withText2", type: ActiveFedora::SimpleDatastream, autocreate: true do |m|
m.field "fubar", :text
end
has_attributes :fubar, datastream: 'withText', multiple: true
has_attributes :swank, datastream: 'someData', multiple: true
Deprecation.silence(ActiveFedora::Attributes) do
has_attributes :fubar, datastream: 'withText', multiple: true
has_attributes :swank, datastream: 'someData', multiple: true
end
end

class FooAdaptation < ActiveFedora::Base
Expand Down

0 comments on commit 9bc5537

Please sign in to comment.