dragonfly 0.1.6 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

Files changed (69) hide show
  1. data/.yardopts +4 -0
  2. data/{README.markdown → README.md} +12 -24
  3. data/Rakefile +6 -6
  4. data/VERSION +1 -1
  5. data/config.rb +1 -3
  6. data/docs.watchr +1 -1
  7. data/dragonfly-rails.gemspec +2 -5
  8. data/dragonfly.gemspec +32 -12
  9. data/extra_docs/ActiveRecord.md +195 -0
  10. data/extra_docs/Analysers.md +63 -0
  11. data/extra_docs/DataStorage.md +33 -0
  12. data/extra_docs/Encoding.md +58 -0
  13. data/extra_docs/GettingStarted.md +114 -0
  14. data/extra_docs/Processing.md +58 -0
  15. data/extra_docs/Shortcuts.md +118 -0
  16. data/extra_docs/UsingWithRails.md +104 -0
  17. data/features/{dragonfly.feature → images.feature} +14 -4
  18. data/features/no_processing.feature +20 -0
  19. data/features/steps/dragonfly_steps.rb +29 -8
  20. data/features/support/env.rb +20 -8
  21. data/generators/dragonfly_app/USAGE +0 -1
  22. data/generators/dragonfly_app/dragonfly_app_generator.rb +1 -13
  23. data/generators/dragonfly_app/templates/metal_file.erb +1 -1
  24. data/lib/dragonfly/active_record_extensions.rb +1 -0
  25. data/lib/dragonfly/active_record_extensions/attachment.rb +52 -6
  26. data/lib/dragonfly/active_record_extensions/validations.rb +26 -6
  27. data/lib/dragonfly/analysis/base.rb +6 -3
  28. data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -6
  29. data/lib/dragonfly/app.rb +53 -35
  30. data/lib/dragonfly/configurable.rb +1 -1
  31. data/lib/dragonfly/data_storage/file_data_store.rb +8 -8
  32. data/lib/dragonfly/delegatable.rb +14 -0
  33. data/lib/dragonfly/delegator.rb +50 -0
  34. data/lib/dragonfly/encoding/base.rb +7 -7
  35. data/lib/dragonfly/encoding/r_magick_encoder.rb +3 -0
  36. data/lib/dragonfly/encoding/transparent_encoder.rb +1 -1
  37. data/lib/dragonfly/extended_temp_object.rb +13 -7
  38. data/lib/dragonfly/parameters.rb +17 -11
  39. data/lib/dragonfly/processing/base.rb +9 -0
  40. data/lib/dragonfly/processing/r_magick_processor.rb +15 -1
  41. data/lib/dragonfly/r_magick_configuration.rb +12 -8
  42. data/lib/dragonfly/rails/images.rb +1 -1
  43. data/lib/dragonfly/temp_object.rb +14 -2
  44. data/lib/dragonfly/url_handler.rb +5 -6
  45. data/samples/sample.docx +0 -0
  46. data/spec/dragonfly/active_record_extensions/model_spec.rb +175 -84
  47. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -8
  48. data/spec/dragonfly/app_spec.rb +3 -3
  49. data/spec/dragonfly/configurable_spec.rb +1 -1
  50. data/spec/dragonfly/data_storage/file_data_store_spec.rb +55 -40
  51. data/spec/dragonfly/delegatable_spec.rb +32 -0
  52. data/spec/dragonfly/delegator_spec.rb +133 -0
  53. data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +28 -0
  54. data/spec/dragonfly/extended_temp_object_spec.rb +5 -5
  55. data/spec/dragonfly/parameters_spec.rb +22 -32
  56. data/spec/dragonfly/processing/rmagick_processor_spec.rb +1 -2
  57. data/spec/dragonfly/temp_object_spec.rb +51 -0
  58. data/spec/dragonfly/url_handler_spec.rb +10 -15
  59. data/yard/handlers/configurable_attr_handler.rb +38 -0
  60. data/yard/setup.rb +9 -0
  61. data/yard/templates/default/fulldoc/html/css/common.css +27 -0
  62. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  63. data/yard/templates/default/module/setup.rb +17 -0
  64. metadata +31 -12
  65. data/features/support/image_helpers.rb +0 -9
  66. data/generators/dragonfly_app/templates/custom_processing.erb +0 -13
  67. data/lib/dragonfly/analysis/analyser.rb +0 -45
  68. data/lib/dragonfly/processing/processor.rb +0 -14
  69. data/spec/dragonfly/analysis/analyser_spec.rb +0 -85
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ -e yard/setup.rb
3
+ --files extra_docs/*
4
+
@@ -7,38 +7,20 @@ It includes an extension for Ruby on Rails to enable easy image handling.
7
7
  For the lazy rails user
8
8
  -----------------------
9
9
 
10
- In environment.rb:
10
+ environment.rb:
11
11
 
12
12
  config.gem 'dragonfly-rails', :lib => 'dragonfly/rails/images'
13
13
  config.middleware.use 'Dragonfly::MiddlewareWithCache', :images
14
14
 
15
15
  Migration:
16
16
 
17
- class AddCoverImageToAlbums < ActiveRecord::Migration
18
-
19
- def self.up
20
- add_column :albums, :cover_image_uid, :string
21
- end
22
-
23
- def self.down
24
- remove_column :albums, :cover_image_uid
25
- end
26
-
27
- end
17
+ add_column :albums, :cover_image_uid, :string
28
18
 
29
19
  Model:
30
20
 
31
21
  class Album < ActiveRecord::Base
32
-
33
-
34
- validates_presence_of :cover_image
35
- validates_size_of :cover_image, :maximum => 500.kilobytes
36
- validates_mime_type_of :cover_image, :in => %w(image/jpeg image/png image/gif)
37
-
38
- image_accessor :cover_image # This provides the reader/writer for cover_image
39
-
40
- image_accessor :some_other_image # have as many as you like - each needs a xxxx_uid column as per migration above
41
-
22
+ image_accessor :cover_image # Defines reader/writer for cover_image
23
+ # ...
42
24
  end
43
25
 
44
26
  View (for uploading via a file field):
@@ -52,6 +34,7 @@ View (for uploading via a file field):
52
34
 
53
35
  View (to display):
54
36
 
37
+ <%= image_tag @album.cover_image.url(:gif) %>
55
38
  <%= image_tag @album.cover_image.url('400x200') %>
56
39
  <%= image_tag @album.cover_image.url('100x100!', :png) %>
57
40
  <%= image_tag @album.cover_image.url('100x100#') %>
@@ -60,12 +43,17 @@ View (to display):
60
43
  ...etc.
61
44
 
62
45
  Using outside of rails, custom storage/processing/encoding/analysis, and more...
63
- ------------------------------------------------------------------------
46
+ --------------------------------------------------------------------------------
64
47
  Dragonfly is primarily a Rack app, the Rails part of it being nothing more than a separate layer on top of the main code, which means you can use it as a standalone app, or with Sinatra, Merb, etc.
65
48
 
66
49
  It is intended to be highly customizable, and is not limited to images, but any data type that could suit on-the-fly processing/encoding.
67
50
 
68
- The docs are in the process of being added, and will appear soon!...
51
+ For more info, consult the <a href="http://yardoc.org/docs/markevans-dragonfly">DOCUMENTATION</a>
52
+
53
+ Issues
54
+ ======
55
+ Please use the <a href="http://github.com/markevans/dragonfly/issues">github issue tracker</a> if you have any issues.
56
+
69
57
 
70
58
  Credits
71
59
  =======
data/Rakefile CHANGED
@@ -10,6 +10,7 @@ begin
10
10
  s.homepage = "http://github.com/markevans/dragonfly"
11
11
  s.authors = ["Mark Evans"]
12
12
  s.add_dependency('rack')
13
+ s.has_rdoc = 'yard'
13
14
  end
14
15
  Jeweler::Tasks.new do |s|
15
16
  s.name = "dragonfly-rails"
@@ -23,7 +24,6 @@ begin
23
24
  s.add_dependency('dragonfly')
24
25
  s.add_dependency('rack')
25
26
  s.add_dependency('rack-cache')
26
- s.add_dependency('mime-types')
27
27
  s.add_dependency('rmagick')
28
28
  end
29
29
  rescue LoadError
@@ -41,12 +41,12 @@ end
41
41
 
42
42
  require 'yard'
43
43
  YARD::Rake::YardocTask.new do |t|
44
- t.files = ['lib/**/*.rb']
45
- t.options = %w(--no-private)
44
+ t.files = ['lib/**/*.rb', 'markdown_docs/*']
45
+ t.options = %w(--no-private -e yard/setup.rb --files extra_docs/*)
46
46
  end
47
47
  YARD::Rake::YardocTask.new 'yard:changed' do |t|
48
- t.files = `git stat | grep '.rb' | grep modified | cut -d' ' -f4`.split
49
- t.options = %w(--no-private)
48
+ t.files = `git stat | grep '.rb' | grep modified | grep -v yard | cut -d' ' -f4`.split
49
+ t.options = %w(--no-private -e yard/setup.rb --files extra_docs/*)
50
50
  end
51
51
 
52
52
  require 'spec/rake/spectask'
@@ -68,4 +68,4 @@ rescue LoadError
68
68
  puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
69
69
  end
70
70
 
71
- task :default => :spec
71
+ task :default => [:spec, :features]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.2.1
data/config.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/lib/dragonfly'
2
2
 
3
- include Dragonfly
4
-
5
3
  APP = Dragonfly::App[:images]
6
- APP.configure_with(RMagickConfiguration)
4
+ APP.configure_with(Dragonfly::RMagickConfiguration)
7
5
  APP.url_handler.protect_from_dos_attacks = false
data/docs.watchr CHANGED
@@ -1 +1 @@
1
- watch( 'lib/.*\.rb' ) {|md| system("rake yard:changed") }
1
+ watch('lib/.*\.rb|yard/.*|extra_docs/.*') {|md| system("rake yard:changed") }
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dragonfly-rails}
8
- s.version = "0.1.6"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mark Evans"]
12
- s.date = %q{2009-11-18}
12
+ s.date = %q{2009-12-11}
13
13
  s.email = %q{mark@new-bamboo.co.uk}
14
14
  s.homepage = %q{http://github.com/markevans/dragonfly}
15
15
  s.rdoc_options = ["--charset=UTF-8"]
@@ -25,20 +25,17 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency(%q<dragonfly>, [">= 0"])
26
26
  s.add_runtime_dependency(%q<rack>, [">= 0"])
27
27
  s.add_runtime_dependency(%q<rack-cache>, [">= 0"])
28
- s.add_runtime_dependency(%q<mime-types>, [">= 0"])
29
28
  s.add_runtime_dependency(%q<rmagick>, [">= 0"])
30
29
  else
31
30
  s.add_dependency(%q<dragonfly>, [">= 0"])
32
31
  s.add_dependency(%q<rack>, [">= 0"])
33
32
  s.add_dependency(%q<rack-cache>, [">= 0"])
34
- s.add_dependency(%q<mime-types>, [">= 0"])
35
33
  s.add_dependency(%q<rmagick>, [">= 0"])
36
34
  end
37
35
  else
38
36
  s.add_dependency(%q<dragonfly>, [">= 0"])
39
37
  s.add_dependency(%q<rack>, [">= 0"])
40
38
  s.add_dependency(%q<rack-cache>, [">= 0"])
41
- s.add_dependency(%q<mime-types>, [">= 0"])
42
39
  s.add_dependency(%q<rmagick>, [">= 0"])
43
40
  end
44
41
  end
data/dragonfly.gemspec CHANGED
@@ -5,20 +5,21 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dragonfly}
8
- s.version = "0.1.6"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mark Evans"]
12
- s.date = %q{2009-11-18}
12
+ s.date = %q{2009-12-11}
13
13
  s.email = %q{mark@new-bamboo.co.uk}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
16
- "README.markdown"
16
+ "README.md"
17
17
  ]
18
18
  s.files = [
19
19
  ".gitignore",
20
+ ".yardopts",
20
21
  "LICENSE",
21
- "README.markdown",
22
+ "README.md",
22
23
  "Rakefile",
23
24
  "VERSION",
24
25
  "config.rb",
@@ -26,14 +27,21 @@ Gem::Specification.new do |s|
26
27
  "docs.watchr",
27
28
  "dragonfly-rails.gemspec",
28
29
  "dragonfly.gemspec",
29
- "features/dragonfly.feature",
30
+ "extra_docs/ActiveRecord.md",
31
+ "extra_docs/Analysers.md",
32
+ "extra_docs/DataStorage.md",
33
+ "extra_docs/Encoding.md",
34
+ "extra_docs/GettingStarted.md",
35
+ "extra_docs/Processing.md",
36
+ "extra_docs/Shortcuts.md",
37
+ "extra_docs/UsingWithRails.md",
38
+ "features/images.feature",
39
+ "features/no_processing.feature",
30
40
  "features/steps/common_steps.rb",
31
41
  "features/steps/dragonfly_steps.rb",
32
42
  "features/support/env.rb",
33
- "features/support/image_helpers.rb",
34
43
  "generators/dragonfly_app/USAGE",
35
44
  "generators/dragonfly_app/dragonfly_app_generator.rb",
36
- "generators/dragonfly_app/templates/custom_processing.erb",
37
45
  "generators/dragonfly_app/templates/initializer.erb",
38
46
  "generators/dragonfly_app/templates/metal_file.erb",
39
47
  "irbrc.rb",
@@ -43,7 +51,6 @@ Gem::Specification.new do |s|
43
51
  "lib/dragonfly/active_record_extensions/class_methods.rb",
44
52
  "lib/dragonfly/active_record_extensions/instance_methods.rb",
45
53
  "lib/dragonfly/active_record_extensions/validations.rb",
46
- "lib/dragonfly/analysis/analyser.rb",
47
54
  "lib/dragonfly/analysis/base.rb",
48
55
  "lib/dragonfly/analysis/file_command_analyser.rb",
49
56
  "lib/dragonfly/analysis/r_magick_analyser.rb",
@@ -55,6 +62,8 @@ Gem::Specification.new do |s|
55
62
  "lib/dragonfly/data_storage/base64_data_store.rb",
56
63
  "lib/dragonfly/data_storage/file_data_store.rb",
57
64
  "lib/dragonfly/data_storage/transparent_data_store.rb",
65
+ "lib/dragonfly/delegatable.rb",
66
+ "lib/dragonfly/delegator.rb",
58
67
  "lib/dragonfly/encoding/base.rb",
59
68
  "lib/dragonfly/encoding/r_magick_encoder.rb",
60
69
  "lib/dragonfly/encoding/transparent_encoder.rb",
@@ -62,7 +71,7 @@ Gem::Specification.new do |s|
62
71
  "lib/dragonfly/middleware.rb",
63
72
  "lib/dragonfly/middleware_with_cache.rb",
64
73
  "lib/dragonfly/parameters.rb",
65
- "lib/dragonfly/processing/processor.rb",
74
+ "lib/dragonfly/processing/base.rb",
66
75
  "lib/dragonfly/processing/r_magick_processor.rb",
67
76
  "lib/dragonfly/r_magick_configuration.rb",
68
77
  "lib/dragonfly/rails/images.rb",
@@ -71,6 +80,7 @@ Gem::Specification.new do |s|
71
80
  "samples/beach.png",
72
81
  "samples/egg.png",
73
82
  "samples/round.gif",
83
+ "samples/sample.docx",
74
84
  "samples/taj.jpg",
75
85
  "spec/argument_matchers.rb",
76
86
  "spec/dragonfly/active_record_extensions/attachment_spec.rb",
@@ -79,12 +89,14 @@ Gem::Specification.new do |s|
79
89
  "spec/dragonfly/active_record_extensions/model_spec.rb",
80
90
  "spec/dragonfly/active_record_extensions/models.rb",
81
91
  "spec/dragonfly/active_record_extensions/spec_helper.rb",
82
- "spec/dragonfly/analysis/analyser_spec.rb",
83
92
  "spec/dragonfly/analysis/r_magick_analyser_spec.rb",
84
93
  "spec/dragonfly/app_spec.rb",
85
94
  "spec/dragonfly/configurable_spec.rb",
86
95
  "spec/dragonfly/data_storage/data_store_spec.rb",
87
96
  "spec/dragonfly/data_storage/file_data_store_spec.rb",
97
+ "spec/dragonfly/delegatable_spec.rb",
98
+ "spec/dragonfly/delegator_spec.rb",
99
+ "spec/dragonfly/encoding/r_magick_encoder_spec.rb",
88
100
  "spec/dragonfly/extended_temp_object_spec.rb",
89
101
  "spec/dragonfly/middleware_spec.rb",
90
102
  "spec/dragonfly/middleware_with_cache_spec.rb",
@@ -96,8 +108,14 @@ Gem::Specification.new do |s|
96
108
  "spec/dragonfly_spec.rb",
97
109
  "spec/image_matchers.rb",
98
110
  "spec/simple_matchers.rb",
99
- "spec/spec_helper.rb"
111
+ "spec/spec_helper.rb",
112
+ "yard/handlers/configurable_attr_handler.rb",
113
+ "yard/setup.rb",
114
+ "yard/templates/default/fulldoc/html/css/common.css",
115
+ "yard/templates/default/module/html/configuration_summary.erb",
116
+ "yard/templates/default/module/setup.rb"
100
117
  ]
118
+ s.has_rdoc = %q{yard}
101
119
  s.homepage = %q{http://github.com/markevans/dragonfly}
102
120
  s.rdoc_options = ["--charset=UTF-8"]
103
121
  s.require_paths = ["lib"]
@@ -111,12 +129,14 @@ Gem::Specification.new do |s|
111
129
  "spec/dragonfly/active_record_extensions/model_spec.rb",
112
130
  "spec/dragonfly/active_record_extensions/models.rb",
113
131
  "spec/dragonfly/active_record_extensions/spec_helper.rb",
114
- "spec/dragonfly/analysis/analyser_spec.rb",
115
132
  "spec/dragonfly/analysis/r_magick_analyser_spec.rb",
116
133
  "spec/dragonfly/app_spec.rb",
117
134
  "spec/dragonfly/configurable_spec.rb",
118
135
  "spec/dragonfly/data_storage/data_store_spec.rb",
119
136
  "spec/dragonfly/data_storage/file_data_store_spec.rb",
137
+ "spec/dragonfly/delegatable_spec.rb",
138
+ "spec/dragonfly/delegator_spec.rb",
139
+ "spec/dragonfly/encoding/r_magick_encoder_spec.rb",
120
140
  "spec/dragonfly/extended_temp_object_spec.rb",
121
141
  "spec/dragonfly/middleware_spec.rb",
122
142
  "spec/dragonfly/middleware_with_cache_spec.rb",
@@ -0,0 +1,195 @@
1
+ ActiveRecord Extensions
2
+ =======================
3
+
4
+ Dragonfly provides a module that extends ActiveRecord so that you can access Dragonfly objects as if they were just another model attribute.
5
+
6
+ Registering with ActiveRecord
7
+ -----------------------------
8
+ If you've used a rails generator, or required the file 'dragonfly/rails/images.rb', then this step will be already done for you.
9
+
10
+ Suppose we have a dragonfly app
11
+
12
+ app = Dragonfly::App[:my_app_name]
13
+
14
+ First extend activerecord
15
+
16
+ ActiveRecord::Base.extend Dragonfly::ActiveRecordExtensions
17
+
18
+ Now register the app, giving the prefix for defining accessor methods (in this case 'image')
19
+
20
+ ActiveRecord::Base.register_dragonfly_app(:image, app)
21
+
22
+ Adding accessors
23
+ ----------------
24
+ Now we have the method `image_accessor` available in our model classes, which we can use as many times as we like
25
+
26
+ class Album
27
+ image_accessor :cover_image
28
+ image_accessor :band_photo # Note: this is a different image altogether, not a thumbnail of cover_image
29
+ end
30
+
31
+ For each accessor, we need a database field ..._uid, as a string, so in our migrations:
32
+
33
+ class MyMigration < ActiveRecord::Migration
34
+
35
+ def self.up
36
+ add_column :albums, :cover_image_uid, :string
37
+ add_column :albums, :band_photo_uid, :string
38
+ end
39
+
40
+ def self.down
41
+ remove_column :albums, :cover_image_uid
42
+ remove_column :albums, :band_photo_uid
43
+ end
44
+
45
+ end
46
+
47
+ Using the accessors
48
+ -------------------
49
+
50
+ We can use the attribute much like other other active record attributes:
51
+
52
+ album = Album.new
53
+
54
+ album.cover_image = "\377???JFIF\000\..." # can assign as a string...
55
+ album.cover_image = File.new('path/to/my_image.png') # ... or as a file...
56
+ album.cover_image = some_tempfile # ... or as a tempfile
57
+
58
+ album.cover_image # => #<Dragonfly::ActiveRecordExtensions::Attachment:0x103ef6128...
59
+
60
+ album.cover_image = nil
61
+ album.cover_image # => nil
62
+
63
+ We can inspect properties of the attribute
64
+
65
+ album.cover_image.width # => 280
66
+ album.cover_image.height # => 140
67
+ album.cover_image.number_of_colours # => 34703 (can also use American spelling)
68
+ album.cover_image.mime_type # => 'image/png'
69
+
70
+ The properties available (i.e. 'width', etc.) come from the app's registered analysers - see {file:Analysers.md Analysers}.
71
+
72
+ We can play around with the data
73
+
74
+ album.cover_image.data # => "\377???JFIF\000\..."
75
+ album.cover_image.to_file('out.png') # writes to file 'out.png' and returns a readable file object
76
+ album.cover_image.tempfile # => #<File:/var/folders/st/strHv74sH044JPabSiODz... i.e. a tempfile holding the data
77
+ album.cover_image.file # alias for tempfile, above
78
+ album.cover_image.path # => '/var/folders/st/strHv74sH044JPabSiODz...' i.e. the path of the tempfile
79
+ album.cover_image.size # => 134507 (size in bytes)
80
+
81
+ We can process the data
82
+
83
+ temp_object = album.cover_image.process(:resize, :geometry => '20x20') # returns an ExtendedTempObject, with similar properties
84
+ temp_object.width # => 20
85
+ album.cover_image.width # => 280 (no change)
86
+
87
+ album.cover_image.process!(:resize, :geometry => '20x20') # (operates on self)
88
+ album.cover_image.width # => 20
89
+
90
+ The available processing methods available (i.e. 'resize', etc.) come from the {Dragonfly} app's registered processors - see {file:Processing.md Processing}
91
+
92
+ We can encode the data
93
+
94
+ temp_object = album.cover_image.encode(:gif) # returns an ExtendedTempObject, with similar properties
95
+ temp_object.mime_type # => 'image/gif'
96
+ album.cover_image.mime_type # => 'image/png' (no change)
97
+
98
+ album.cover_image.encode!(:gif) # (operates on self)
99
+ album.cover_image.mime_type # => 'image/gif'
100
+
101
+ The encoding is implemented by the {Dragonfly} app's registered encoders (which will usually just be one) - see {file:Encoding.md Encoding}
102
+
103
+ If we have a combination of processing and encoding that we often use, e.g.
104
+
105
+ album.cover_image.process(:resize_and_crop, :width => 300, :height => 200, :gravity => 'nw').encode(:gif)
106
+
107
+ then we can register a shortcut (see {file:Shortcuts.md Shortcuts}) and use that with `transform`, e.g.
108
+
109
+ album.cover_image.transform('300x200#nw', :gif) # returns an ExtendedTempObject, like process and encode above
110
+ album.cover_image.transform!('300x200#nw', :gif) # (operates on self)
111
+
112
+ Persisting
113
+ ----------
114
+ When the model is saved, a before_save callback persists the data to the {Dragonfly::App App}'s configured datastore (see {file:DataStorage.md DataStorage})
115
+ The uid column is then filled in.
116
+
117
+ album = Album.new
118
+
119
+ album.cover_image_uid # => nil
120
+
121
+ album.cover_image = File.new('path/to/my_image.png')
122
+ album.cover_image_uid # => 'PENDING' (actually a Dragonfly::ActiveRecordExtensions::PendingUID)
123
+
124
+ album.save
125
+ album.cover_image_uid # => '2009/12/05/170406_file' (some unique uid, used by the datastore)
126
+
127
+ URLs
128
+ ----
129
+ Once the model is saved, we can get a url for the image (which is served by the Dragonfly {Dragonfly::App App} itself):
130
+
131
+ album.cover_image.url # => '/media/2009/12/05/170406_file' (Note there is no extension)
132
+ album.cover_image.url(:png) # => '/media/2009/12/05/170406_file.png'
133
+ album.cover_image.url('300x200#nw', :gif) # => '/media/2009/12/05/170406_file.tif?m=resize_and_crop&o[height]=...'
134
+
135
+ Note that any arguments given to `url` are of the same form as those used for `transform`, i.e. those registered as shortcuts (see {file:Shortcuts.md Shortcuts})
136
+ These urls are what you would use in, for example, html views.
137
+
138
+ Validations
139
+ -----------
140
+ `validates_presence_of` and `validates_size_of` work out of the box, and Dragonfly provides two more,
141
+ `validates_property` and `validates_mime_type_of` (which is actually just a thin wrapper around `validates_property`).
142
+
143
+ class Album
144
+
145
+ validates_presence_of :cover_image
146
+ validates_size_of :cover_image, :maximum => 500.kilobytes
147
+ validates_mime_type_of :cover_image, :in => %w(image/jpeg image/png image/gif)
148
+ validates_property :width, :of => :cover_image, :in => (0..400)
149
+
150
+ # ...
151
+ end
152
+
153
+ The property argument of `validates_property` will generally be one of the registered analyser properties as described in {file:Analysers.md Analysers}.
154
+ However it would actually work for arbitrary properties, including those of non-dragonfly model attributes.
155
+ See {Dragonfly::ActiveRecordExtensions::Validations Validations} for more info.
156
+
157
+ Name and extension
158
+ ------------------
159
+ If the object assigned is a file, or responds to `original_filename` (as is the case with file uploads in Rails, etc.), then `name` and `ext` will be set.
160
+
161
+ album.cover_image = File.new('path/to/my_image.png')
162
+
163
+ album.cover_image.name # => 'my_image.png'
164
+ album.cover_image.ext # => 'png'
165
+
166
+
167
+ 'Magic' Attributes
168
+ ------------------
169
+ The only model column necessary for the migration, as described above, is the uid column, e.g. `cover_image_uid`.
170
+ However, in many cases you may want to record some other properties in the database, whether it be for using in sql queries, or
171
+ for caching an attribute for performance reasons.
172
+
173
+ For the properties `name`, `ext`, `size` and any of the registered analysis methods (e.g. `width`, etc. in the examples above),
174
+ this is done automatically for you, if the corresponding column exists.
175
+ For example:
176
+
177
+ In the migration:
178
+
179
+ add_column :albums, :cover_image_ext, :string
180
+ add_column :albums, :cover_image_width, :integer
181
+
182
+ These are automatically set when assigned:
183
+
184
+ album.cover_image = File.new('path/to/my_image.png')
185
+
186
+ album.cover_image_ext # => 'png'
187
+ album.cover_image_width # => 280
188
+
189
+ They can be used to avoid retrieving data from the datastore for analysis (e.g. if you've used something like S3 to store data - see {file:DataStorage.md DataStorage})
190
+
191
+ album = Album.first
192
+
193
+ album.cover_image.ext # => 'png' - no need to retrieve data - takes it from `cover_image_ext`
194
+ album.cover_image.width # => 280 - no need to retrieve data - takes it from `cover_image_width`
195
+ album.cover_image.size # => 134507 - but it needs to retrieve data from the data store, then analyse