Open no-reply opened 5 years ago
One approach to this issue is to move the optimistic lock token out of #attributes
.
That probably constitutes a major release, and might involve a bit of work since there's some use of the Dry::Types
, but my intuition is that it's the best approach.
It looks like both Memory and Fedora are using the current Time of the object's instantiation to create the lock tokens:
The other option is we just change equality to be something like AR, where if it's persisted it ==
if the two share an ID/class (thanks @jrochkind for digging that up)
i'll express a preference for Dry::Struct
-style equality. it seems so easy to do ID equality as a client that using #==
for it seems wasteful. resource.id == other.id
for reference: include Dry::Equalizer(:id)
ought to be all it takes to implement #==
as AR-style ID equality; including the class check.
I'm having a hard time figuring out how we can move this forward. I think I need some use cases where I want two things to be equal to one another if they have different lock tokens.
@tpendragon: if i recall, the motivating need here was Sets. for example, i think the behavior of the following code varies depending on otherwise irrelevant details of the adapters optimistic locking behavior:
class Permission < Valkyrie::Resource
enable_optimistic_locking
attribute :mode
attribute :user
end
class ResourceWithPermissions < Valkyrie::Resource
enable_optimistic_locking
attribute :permissions, Valkyrie::Types::Set.of(Permission)
end
p = Permission.new(mode: :read, user: 'user_key')
p = Valkyrie.config.metadata_adapter.persister.save(resource: p)
resource = ResourceWithPermissions.new(permissions: [p])
p2 = Valkyrie.config.metadata_adapter.query_service.find_by(id: p.id)
resource.permissions << p2
a practical example exists in Hyrax: https://github.com/samvera/hyrax/blob/f8706bc91d1caa3a4cdd73401cc7d081ec158437/app/models/hyrax/permission.rb#L13
but honestly, i think it would be desirable as a matter of principle for Valkyrie.config.metadata_adapter.query.find_by(id: 'some_id') == Valkyrie.config.metadata_adapter.query.find_by(id: 'some_id')
to be true for all adapters.
Equality is currently based on the default
Dry::Struct
implementation, which compares allResourceClass.__attributes__
. This includes::Valkyrie::Persistence::OptimisticLockToken
, which should likely be excluded.We may want to consider excluding other reserved attributes.