samvera / active_fedora

A Rails interface to the Fedora repository, akin to ActiveModel
Other
54 stars 63 forks source link

ActiveFedora::Associations::Builder::BelongsTo option :optional does not work #1495

Open fritzfreiheit opened 1 year ago

fritzfreiheit commented 1 year ago

ActiveFedora::Associations::Builder::BelongsTo option :optional can't be specified.

See: Hydra::AccessControls::Embargoable belongs_to :embargo, optional: true, predicate: Hydra::ACL.hasEmbargo, class_name: 'Hydra::AccessControls::Embargo', autosave: true

throws an exception as follows:

hyrax-app-1 | 8: from /usr/local/bundle/gems/activesupport-6.1.7.2/lib/active_support/concern.rb:136:in `class_eval'
hyrax-app-1 | 7: from /app/samvera/hyrax-engine/app/models/concerns/hydra/access_controls/embargoable.rb:12:in `block in <module:Embargoable>'
hyrax-app-1 | 6: from /app/samvera/hyrax-engine/lib/active_fedora/associations.rb:239:in `belongs_to'
hyrax-app-1 | 5: from /app/samvera/hyrax-engine/lib/active_fedora/associations/builder/association.rb:21:in `build'
hyrax-app-1 | 4: from /app/samvera/hyrax-engine/lib/active_fedora/associations/builder/association.rb:30:in `create_reflection'
hyrax-app-1 | 3: from /app/samvera/hyrax-engine/lib/active_fedora/associations/builder/association.rb:61:in `validate_options'
hyrax-app-1 | 2: from /usr/local/bundle/gems/activesupport-6.1.7.2/lib/active_support/core_ext/hash/keys.rb:50:in `assert_valid_keys'
hyrax-app-1 | 1: from /usr/local/bundle/gems/activesupport-6.1.7.2/lib/active_support/core_ext/hash/keys.rb:50:in `each_key'
hyrax-app-1 | /usr/local/bundle/gems/activesupport-6.1.7.2/lib/active_support/core_ext/hash/keys.rb:52:in `block in assert_valid_keys': Unknown key: :optional. Valid keys are: :class_name, :predicate, :type_validator, :autosave (ArgumentError)

ActiveFedora::Associations#belongs_to does not define an :optional option.

Experimentally updating the code (by adding :optional to ActiveFedora::Associations::Builder::Association::VALID_OPTIONS, which is too general. ActiveFedora::Associations::Builder::BelongsTo option :optional should recognize it.) I was able to demonstrate that the ActiveFedora::AutosaveAssociation#save_belongs_to_association still creates an empty dependent object.

ActiveFedora::AutosaveAssociation#save_belongs_to_association should not create objects that :belong_to another object when they are declared optional.

I was able to fix this by using changing the code as follows (lines 4-9 have have been added or modfied):

  1. if autosave && record.marked_for_destruction?
  2. record.destroy
  3. elsif autosave != false
  4. optional = true == reflection.options[:optional] # update for optional belongs_to
  5. if optional && !record.changed?
  6. # skip
  7. else
  8. saved = record.save(validate: false) if record.new_record? || (autosave && record.changed_for_autosave?)
  9. end
  10. if association.updated?
  11. self[reflection.foreign_key] = record.id
  12. association.loaded!
  13. end
  14. ``
  15. saved if autosave
  16. end

Associated issue: Hyrax-5092 / https://github.com/samvera/hyrax/issues/5902