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, simply 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, simply 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
will always be set. content_hash
won’t be set until the record is being saved.
If you don’t care about filenames and content types and just want to store a binary blob, you can also just set the data
attribute.
my_data = File.read('document.pdf')
document.update(data: my_data)
The data won’t be stored until the record is saved, and not unless the record is valid.
To retrieve your data, simply 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, simply 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 ⇒ Object
Returns the data as a binary string, or nil if no data has been set.
-
#data=(raw_data) ⇒ Object
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.
- #dis_stored? ⇒ Boolean
-
#file=(file) ⇒ Object
Assigns new data from an uploaded file.
Instance Method Details
#data ⇒ Object
Returns the data as a binary string, or nil if no data has been set.
93 94 95 |
# File 'lib/dis/model.rb', line 93 def data dis_data.read end |
#data=(raw_data) ⇒ Object
Assigns new data. This also sets content_length
, and resets content_hash
to nil.
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/dis/model.rb', line 104 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.
98 99 100 |
# File 'lib/dis/model.rb', line 98 def data? dis_data.any? end |
#data_changed? ⇒ Boolean
Returns true if the data has been changed since the object was last saved.
117 118 119 |
# File 'lib/dis/model.rb', line 117 def data_changed? changes.include?("data") end |
#dis_stored? ⇒ Boolean
121 122 123 |
# File 'lib/dis/model.rb', line 121 def dis_stored? !(new_record? || data_changed?) end |
#file=(file) ⇒ Object
Assigns new data from an uploaded file. In addition to the actions performed by data=
, this will set content_type
and filename
.
128 129 130 131 132 |
# File 'lib/dis/model.rb', line 128 def file=(file) self.data = file dis_set :content_type, file.content_type dis_set :filename, file.original_filename end |