Module: Dis::Model
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/dis/model.rb,
lib/dis/model/data.rb,
lib/dis/model/class_methods.rb
Overview
Dis Model
ActiveModel extension for the model holding your data. To use it, include the module in your model:
class Document < ActiveRecord::Base
include Dis::Model
end
You’ll need to define a few attributes in your database table. Here’s a minimal migration:
create_table :documents do |t|
t.string :content_hash
t.string :content_type
t.integer :content_length
t.string :filename
end
You can override the names of any of these by setting dis_attributes.
class Document < ActiveRecord::Base
include Dis::Model
self.dis_attributes = {
filename: :my_filename,
content_length: :filesize
}
end
Usage
To save a file, assign to the file attribute.
document = Document.create(file: params.permit(:file))
content_type and filename will automatically be set if the supplied object quacks like a file. content_length and content_hash will always be set.
To store a binary blob without filenames or content types, set the data attribute directly.
my_data = File.read('document.pdf')
document.update(data: my_data)
The data won’t be stored until the record is saved, and only if the record is valid.
To retrieve your data, read the data attribute. The file will be lazily loaded from the store on demand and cached in memory as long as the record stays in scope.
my_data = document.data
Destroying a record will delete the file from the store, unless another record also refers to the same hash. Similarly, stale files will be purged when content changes.
Validations
No validation is performed by default. If you want to ensure that data is present, use the validates_data_presence method.
class Document < ActiveRecord::Base
include Dis::Model
validates_data_presence
end
If you want to validate content types, size or similar, use standard Rails validations on the metadata attributes:
validates :content_type, presence: true, format: /\Aapplication\/pdf\z/
validates :filename, presence: true, format: /\A[\w_\-\.]+\.pdf\z/i
validates :content_length, numericality: { less_than: 5.megabytes }
Defined Under Namespace
Modules: ClassMethods Classes: Data
Instance Method Summary collapse
-
#data ⇒ String?
Returns the data as a binary string, or nil if no data has been set.
-
#data=(raw_data) ⇒ void
Assigns new data.
-
#data? ⇒ Boolean
Returns true if data is set.
-
#data_changed? ⇒ Boolean
Returns true if the data has been changed since the object was last saved.
-
#data_file_path ⇒ String
Returns a file path to the data, preferring local storage paths.
-
#dis_stored? ⇒ Boolean
Returns true if the record has been persisted and its data has not been changed since the last save.
-
#file=(file) ⇒ void
Assigns new data from an uploaded file.
-
#tempfile ⇒ Tempfile
Returns the data as a temporary file.
Instance Method Details
#data ⇒ String?
Returns the data as a binary string, or nil if no data has been set.
96 97 98 |
# File 'lib/dis/model.rb', line 96 def data dis_data.read end |
#data=(raw_data) ⇒ void
This method returns an undefined value.
Assigns new data. This also sets content_length and content_hash.
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/dis/model.rb', line 112 def data=(raw_data) new_data = Dis::Model::Data.new(self, raw_data) attribute_will_change!("data") unless new_data == dis_data @dis_data = new_data dis_set :content_hash, if raw_data.nil? nil else Storage.file_digest(new_data.read) end dis_set :content_length, dis_data.content_length end |
#data? ⇒ Boolean
Returns true if data is set.
103 104 105 |
# File 'lib/dis/model.rb', line 103 def data? dis_data.any? end |
#data_changed? ⇒ Boolean
Returns true if the data has been changed since the object was last saved.
128 129 130 |
# File 'lib/dis/model.rb', line 128 def data_changed? changes.include?("data") end |
#data_file_path ⇒ String
Returns a file path to the data, preferring local storage paths. Falls back to a tempfile path if no local layer has the file.
159 160 161 |
# File 'lib/dis/model.rb', line 159 def data_file_path dis_data.file_path end |
#dis_stored? ⇒ Boolean
Returns true if the record has been persisted and its data has not been changed since the last save.
136 137 138 |
# File 'lib/dis/model.rb', line 136 def dis_stored? !(new_record? || data_changed?) end |
#file=(file) ⇒ void
This method returns an undefined value.
Assigns new data from an uploaded file. In addition to the actions performed by #data=, this will set content_type and filename.
148 149 150 151 152 |
# File 'lib/dis/model.rb', line 148 def file=(file) self.data = file dis_set :content_type, file.content_type dis_set :filename, file.original_filename end |
#tempfile ⇒ Tempfile
Returns the data as a temporary file.
166 |
# File 'lib/dis/model.rb', line 166 delegate :tempfile, to: :dis_data |