class CarrierWave::FileCardUploader
Takes care of the file upload for cards with attached files. Most of the upload behaviour depends on the card itself. (e.g. card type and storage option chosen for the card). So in contrary to CarrierWave's default uploader we depend very much on the model (= card object) to get the correct paths for retrieving and storing the file.
Cards that support attachments (by default those are cards of type “file” and “image”) accept a file handle as a card attribute.
@example Attaching a file to a file card
Card.create name: "file card", type: :file, file: File.new(path_to_file)
@example Attaching a image to a image card
Card.create name: "file card", type: :image, image: File.new(path_to_image)
It's possible to upload files using a url. The card attribute for that is remote_<attachment_type>_url
@example Create a file card using a remote url
Card.create name: "file_card", type: :file, remote_file_url: "http://a.file.in/the.web"
@example Updating a image card using a remote url
card.update remote_image_url: "http://a.image/somewhere.png"
## Storage types You can choose between four different storage options
- coded: These files are in the codebase, like the default logo. Every view is a decko request. - local: Uploaded files which are stored in a local upload directory (upload path is configurable via config.paths["files"]). If read permissions are set such that "Anyone" can read, then there is a symlink from the public directory. Otherwise every view is a decko request. - cloud: You can configure buckets that refer to an external storage service. Link is rendered as absolute url - web: A fixed url (to external source). No upload or other file processing. Link is just the saved url.
Currently, there is no web interface that let's a user or administrator choose a storage option for a specific card or set of cards. There is only a global config option to set the storage type for all new uploads (config.storage_type). On the *admin card it's possible to update all existing file cards according to the current global config.
Storage types for single cards can be changed by developers using the card attributes “storage_type”, “bucket”, and “mod”.
@example Creating a hard-coded file
Card.create name: "file card", type_id: Card::FileID, file: File.new(path), storage_type: :coded, mod: "account"
@example Moving a file to a cloud service
# my_deck/config/application.rb: config.file_buckets = { aws_bucket: { provider: "fog/aws", directory: "bucket-name", subdirectory: "files", credentials: { provider: 'AWS' # required aws_access_key_id: 'key' # required aws_secret_access_key: 'secret-key' # required public: true, } } # decko console or rake task: card.update storage_type: :cloud, bucket: :aws_bucket
@example Creating a file card with fixed external link
Card.create name: "file card", type_id: Card::FileID, content: "http://animals.org/cat.png" storage_type: :web Card.create name: "file card", type_id: Card::FileID, file: "http://animals.org/cat.png" storage_type: :web
Depending on the storage type the uploader uses the following paths and identifiers. ### Identifier (stored in the database as db_content
)
- coded: :codename/mod_name.ext - local: ~card_id/action_id.ext - cloud: (bucket)/card_id/action_id.ext - web: http://url
### Storage path
- coded: mod_dir/file/codename/type_code(-variant).ext (no colon on codename!) - local: files_dir/card_id/action_id(-variant).ext (no tilde on id!) - cloud: bucket/bucket_subdir/id/action_id(-variant).ext - web: no storage
Variants are only used for images. Possible options are icon|small|medium|large|original. files_dir, bucket, and bucket_subdir can be changed via config options.
### Supported url patterns mark.ext mark/revision.ext mark/revision-variant.ext /files/mark/revision-variant.ext # <- public symlink if readable by
# "Anyone"
<mark> can be one of the following options
-
<card name>
-
~<card id>
-
:<code name>
<revision> is the mod name if the file is coded or and action_id
in any case
Examples: *logo.png ~22/33-medium.png # local :yeti_skin/standard-large.png # coded
Constants
- CONFIG_CREDENTIAL_OPTIONS
- CONFIG_OPTIONS
- STORAGE_TYPES
Attributes
Public Instance Methods
# File lib/carrier_wave/file_card_uploader.rb, line 208 def action_id model.selected_content_action_id || action_id_stand_in end
# File lib/carrier_wave/file_card_uploader.rb, line 221 def asset_host bucket_config(:asset_host) || super end
# File lib/carrier_wave/file_card_uploader.rb, line 217 def bucket_config option @model.bucket_config[option] end
# File lib/carrier_wave/file_card_uploader.rb, line 200 def create_versions? new_file model.create_versions? new_file end
generate identifier that gets stored in the card's db_content
field @param opts [Hash] generate an identifier using the given storage options
instead of the storage options derived from the model and the global configuration
@option opts [Symbol] storage_type @option opts [String] mod @option opts [Symbol] bucket
# File lib/carrier_wave/file_card_uploader.rb, line 170 def db_content opts={} model.with_storage_options opts do return model.content if model.web? return "" unless file.present? "%s/%s" % [file_dir, url_filename] end end
# File lib/carrier_wave/file_card_uploader.rb, line 154 def extension case when file&.extension.present? then ".#{file.extension}" when card_content = model.content then File.extname(card_content) when orig = original_filename then File.extname(orig) else "" end.downcase end
# File lib/carrier_wave/file_card_uploader.rb, line 146 def filename if model.coded? "#{model.type_code}#{extension}" else "#{action_id}#{extension}" end end
# File lib/carrier_wave/file_card_uploader.rb, line 204 def original_filename @original_filename ||= model.selected_action&.comment end
@option opts [Symbol] :absolute - return absolute url
# File lib/carrier_wave/file_card_uploader.rb, line 190 def url opts={} if model.cloud? file&.url elsif model.web? model.content else local_url opts end end
# File lib/carrier_wave/file_card_uploader.rb, line 179 def url_filename opts={} model.with_storage_options opts do if model.coded? "#{model.mod}#{extension}" else "#{action_id}#{extension}" end end end
# File lib/carrier_wave/file_card_uploader.rb, line 142 def valid? extension.present? end
Private Instance Methods
used as action_id
in the filename if card is not actionable?
# File lib/carrier_wave/file_card_uploader.rb, line 229 def action_id_stand_in Time.now.to_i end
# File lib/carrier_wave/file_card_uploader.rb, line 233 def storage case @model.storage_type when :cloud Storage::Fog.new self else Storage::File.new self end end