File upload strategies
There is no "right" way to add file to entity via ckanext-files. Everything depends on your use-case and here you can find a few different ways to combine file and arbitrary entity.
Attach existing file and then transfer ownership via API
The simplest option is just saving file ID inside a field of the entity. It's recommended to transfer file ownership to the entity and pin the file.
ckanapi action package_patch id=PACKAGE_ID attachment_id=FILE_ID
ckanapi action files_transfer_ownership id=FILE_ID \
owner_type=package owner_id=PACKAGE_ID pin=true
Pros:
- simple and transparent
Cons:
- it's easy to forget about ownership transfer and leave the entity with the inaccessible file
- after entity got reference to file and before ownership is transfered data may be considered invalid.
Automatically transfer ownership using validator
Add files_transfer_ownership(owner_type)
to the validation schema of
entity. When it validated, ownership transfer task is queued and file
automatically transfered to the entity after the update.
Pros:
- minimal amount of changes if metadata schema already modified
- relationships between owner and file are up-to-date after any modification
Cons:
- works only with files uploaded in advance and cannot handle native implementation of resource form
Upload file and assign owner via queued task
Add a field that accepts uploaded file. The action itself does not process the upload. Instead create a validator for the upload field, that will schedule a task for file upload and ownership transfer.
In this way, if action is failed, no upload happens and you don't need to do anything with the file, as it never left server's temporal directory. If action finished without an error, the task is executed and file uploaded/attached to action result.
Pros:
- can be used together with native group/user/resource form after small modification of CKAN core.
- handles upload inside other action as an atomic operation
Cons:
- you have to validate file before upload happens to prevent situation when action finished successfully but then upload failed because of file's content type or size.
- tasks themselves are experimental and it's not recommended to put a lot of logic into them
- there are just too many things that can go wrong
Add a new action that combines uploads, modifications and ownership transfer
If you want to add attachmen to dataset, create a separate action that accepts
dataset ID and uploaded file. Internally it will upload the file by calling
files_file_create
, then update dataset via packaage_patch
and finally
transfer ownership via files_transfer_ownership
.
Pros:
- no magic. Everything is described in the new action
- can be extracted into shared extension and used across multiple portals
Cons:
- if you need to upload multiple files and update multipe fields, action quickly becomes too compicated.
- integration with existing workflows, like dataset/resource creation is hard. You have to override existing views or create a brand new ones.