paperclip_database 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/.document +5 -0
  2. data/.gitignore +54 -0
  3. data/.rspec +1 -0
  4. data/Appraisals +14 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +102 -0
  7. data/LICENSE.txt +26 -0
  8. data/README.rdoc +19 -0
  9. data/Rakefile +41 -0
  10. data/features/basic_integration.feature +29 -0
  11. data/features/step_definitions/html_steps.rb +15 -0
  12. data/features/step_definitions/paperclip_database_steps.rb +0 -0
  13. data/features/step_definitions/rails_steps.rb +193 -0
  14. data/features/step_definitions/web_steps.rb +209 -0
  15. data/features/support/env.rb +15 -0
  16. data/features/support/fakeweb.rb +3 -0
  17. data/features/support/paths.rb +28 -0
  18. data/features/support/rails.rb +46 -0
  19. data/features/support/selectors.rb +19 -0
  20. data/gemfiles/rails2.gemfile +8 -0
  21. data/gemfiles/rails3.gemfile +8 -0
  22. data/gemfiles/rails3_1.gemfile +8 -0
  23. data/generators/paperclip_database/USAGE +5 -0
  24. data/generators/paperclip_database/paperclip_database_generator.rb +28 -0
  25. data/generators/paperclip_database/templates/paperclip_database_migration.rb.erb +17 -0
  26. data/generators/templates/paperclip_database_migration.rb.erb +17 -0
  27. data/lib/generators/paperclip_database/USAGE +8 -0
  28. data/lib/generators/paperclip_database/paperclip_database_generator.rb +33 -0
  29. data/lib/generators/paperclip_database/templates/paperclip_database_migration.rb.erb +17 -0
  30. data/lib/paperclip/storage/database.rb +198 -0
  31. data/lib/paperclip_database/version.rb +3 -0
  32. data/lib/paperclip_database.rb +4 -0
  33. data/paperclip_database.gemspec +37 -0
  34. data/rails/init.rb +3 -0
  35. data/spec/paperclip_database_spec.rb +7 -0
  36. data/spec/spec_helper.rb +12 -0
  37. data/test/fixtures/5k.png +0 -0
  38. metadata +199 -0
@@ -0,0 +1,209 @@
1
+ # TL;DR: YOU SHOULD DELETE THIS FILE
2
+ #
3
+ # This file was generated by Cucumber-Rails and is only here to get you a head start
4
+ # These step definitions are thin wrappers around the Capybara/Webrat API that lets you
5
+ # visit pages, interact with widgets and make assertions about page content.
6
+ #
7
+ # If you use these step definitions as basis for your features you will quickly end up
8
+ # with features that are:
9
+ #
10
+ # * Hard to maintain
11
+ # * Verbose to read
12
+ #
13
+ # A much better approach is to write your own higher level step definitions, following
14
+ # the advice in the following blog posts:
15
+ #
16
+ # * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
17
+ # * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
18
+ # * http://elabs.se/blog/15-you-re-cuking-it-wrong
19
+ #
20
+
21
+
22
+ require 'uri'
23
+ require 'cgi'
24
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
25
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
26
+
27
+ module WithinHelpers
28
+ def with_scope(locator)
29
+ locator ? within(*selector_for(locator)) { yield } : yield
30
+ end
31
+ end
32
+ World(WithinHelpers)
33
+
34
+ # Single-line step scoper
35
+ When /^(.*) within (.*[^:])$/ do |step, parent|
36
+ with_scope(parent) { When step }
37
+ end
38
+
39
+ # Multi-line step scoper
40
+ When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
41
+ with_scope(parent) { When "#{step}:", table_or_string }
42
+ end
43
+
44
+ Given /^(?:|I )am on (.+)$/ do |page_name|
45
+ visit path_to(page_name)
46
+ end
47
+
48
+ When /^(?:|I )go to (.+)$/ do |page_name|
49
+ visit path_to(page_name)
50
+ end
51
+
52
+ When /^(?:|I )press "([^"]*)"$/ do |button|
53
+ click_button(button)
54
+ end
55
+
56
+ When /^(?:|I )follow "([^"]*)"$/ do |link|
57
+ click_link(link)
58
+ end
59
+
60
+ When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
61
+ fill_in(field, :with => value)
62
+ end
63
+
64
+ When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
65
+ fill_in(field, :with => value)
66
+ end
67
+
68
+ # Use this to fill in an entire form with data from a table. Example:
69
+ #
70
+ # When I fill in the following:
71
+ # | Account Number | 5002 |
72
+ # | Expiry date | 2009-11-01 |
73
+ # | Note | Nice guy |
74
+ # | Wants Email? | |
75
+ #
76
+ # TODO: Add support for checkbox, select og option
77
+ # based on naming conventions.
78
+ #
79
+ When /^(?:|I )fill in the following:$/ do |fields|
80
+ fields.rows_hash.each do |name, value|
81
+ When %{I fill in "#{name}" with "#{value}"}
82
+ end
83
+ end
84
+
85
+ When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
86
+ select(value, :from => field)
87
+ end
88
+
89
+ When /^(?:|I )check "([^"]*)"$/ do |field|
90
+ check(field)
91
+ end
92
+
93
+ When /^(?:|I )uncheck "([^"]*)"$/ do |field|
94
+ uncheck(field)
95
+ end
96
+
97
+ When /^(?:|I )choose "([^"]*)"$/ do |field|
98
+ choose(field)
99
+ end
100
+
101
+ When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
102
+ attach_file(field, File.expand_path(path))
103
+ end
104
+
105
+ Then /^(?:|I )should see "([^"]*)"$/ do |text|
106
+ if page.respond_to? :should
107
+ page.should have_content(text)
108
+ else
109
+ assert page.has_content?(text)
110
+ end
111
+ end
112
+
113
+ Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
114
+ regexp = Regexp.new(regexp)
115
+
116
+ if page.respond_to? :should
117
+ page.should have_xpath('//*', :text => regexp)
118
+ else
119
+ assert page.has_xpath?('//*', :text => regexp)
120
+ end
121
+ end
122
+
123
+ Then /^(?:|I )should not see "([^"]*)"$/ do |text|
124
+ if page.respond_to? :should
125
+ page.should have_no_content(text)
126
+ else
127
+ assert page.has_no_content?(text)
128
+ end
129
+ end
130
+
131
+ Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
132
+ regexp = Regexp.new(regexp)
133
+
134
+ if page.respond_to? :should
135
+ page.should have_no_xpath('//*', :text => regexp)
136
+ else
137
+ assert page.has_no_xpath?('//*', :text => regexp)
138
+ end
139
+ end
140
+
141
+ Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
142
+ with_scope(parent) do
143
+ field = find_field(field)
144
+ if field.value.respond_to? :should
145
+ field.value.should =~ /#{value}/
146
+ else
147
+ assert_match(/#{value}/, field.value)
148
+ end
149
+ end
150
+ end
151
+
152
+ Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
153
+ with_scope(parent) do
154
+ field = find_field(field)
155
+ if field.value.respond_to? :should_not
156
+ field.value.should_not =~ /#{value}/
157
+ else
158
+ assert_no_match(/#{value}/, field.value)
159
+ end
160
+ end
161
+ end
162
+
163
+ Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
164
+ with_scope(parent) do
165
+ field_checked = find_field(label)['checked']
166
+ if field_checked.respond_to? :should
167
+ field_checked.should be_true
168
+ else
169
+ assert field_checked
170
+ end
171
+ end
172
+ end
173
+
174
+ Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
175
+ with_scope(parent) do
176
+ field_checked = find_field(label)['checked']
177
+ if field_checked.respond_to? :should
178
+ field_checked.should be_false
179
+ else
180
+ assert !field_checked
181
+ end
182
+ end
183
+ end
184
+
185
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
186
+ current_path = URI.parse(current_url).path
187
+ if current_path.respond_to? :should
188
+ current_path.should == path_to(page_name)
189
+ else
190
+ assert_equal path_to(page_name), current_path
191
+ end
192
+ end
193
+
194
+ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
195
+ query = URI.parse(current_url).query
196
+ actual_params = query ? CGI.parse(query) : {}
197
+ expected_params = {}
198
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
199
+
200
+ if actual_params.respond_to? :should
201
+ actual_params.should == expected_params
202
+ else
203
+ assert_equal expected_params, actual_params
204
+ end
205
+ end
206
+
207
+ Then /^show me the page$/ do
208
+ save_and_open_page
209
+ end
@@ -0,0 +1,15 @@
1
+ #require 'bundler'
2
+ begin
3
+ Bundler.setup(:default, :development)
4
+ rescue Bundler::BundlerError => e
5
+ $stderr.puts e.message
6
+ $stderr.puts "Run `bundle install` to install missing gems"
7
+ exit e.status_code
8
+ end
9
+
10
+ require 'aruba/cucumber'
11
+ require 'capybara/cucumber'
12
+
13
+ Before do
14
+ @aruba_timeout_seconds = 120
15
+ end
@@ -0,0 +1,3 @@
1
+ require 'fake_web'
2
+
3
+ FakeWeb.allow_net_connect = false
@@ -0,0 +1,28 @@
1
+ module NavigationHelpers
2
+ # Maps a name to a path. Used by the
3
+ #
4
+ # When /^I go to (.+)$/ do |page_name|
5
+ #
6
+ # step definition in web_steps.rb
7
+ #
8
+ def path_to(page_name)
9
+ case page_name
10
+
11
+ when /the home\s?page/
12
+ '/'
13
+ when /the new user page/
14
+ '/users/new'
15
+ else
16
+ begin
17
+ page_name =~ /the (.*) page/
18
+ path_components = $1.split(/\s+/)
19
+ self.send(path_components.push('path').join('_').to_sym)
20
+ rescue Object => e
21
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
22
+ "Now, go and add a mapping in #{__FILE__}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ World(NavigationHelpers)
@@ -0,0 +1,46 @@
1
+ PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze
2
+ APP_NAME = 'testapp'.freeze
3
+ BUNDLE_ENV_VARS = %w(RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE)
4
+ ORIGINAL_BUNDLE_VARS = Hash[ENV.select{ |key,value| BUNDLE_ENV_VARS.include?(key) }]
5
+
6
+ ENV['RAILS_ENV'] = 'test'
7
+
8
+ Before do
9
+ ENV['BUNDLE_GEMFILE'] = File.join(Dir.pwd, ENV['BUNDLE_GEMFILE']) unless ENV['BUNDLE_GEMFILE'].start_with?(Dir.pwd)
10
+ @framework_version = nil
11
+ end
12
+
13
+ After do
14
+ ORIGINAL_BUNDLE_VARS.each_pair do |key, value|
15
+ ENV[key] = value
16
+ end
17
+ end
18
+
19
+ When /^I reset Bundler environment variable$/ do
20
+ BUNDLE_ENV_VARS.each do |key|
21
+ ENV[key] = nil
22
+ end
23
+ end
24
+
25
+ module RailsCommandHelpers
26
+ def framework_version?(version_string)
27
+ framework_version =~ /^#{version_string}/
28
+ end
29
+
30
+ def framework_version
31
+ @framework_version ||= `rails -v`[/^Rails (.+)$/, 1]
32
+ end
33
+
34
+ def new_application_command
35
+ framework_version?("3") ? "rails new" : "rails"
36
+ end
37
+
38
+ def generator_command
39
+ framework_version?("3") ? "script/rails generate" : "script/generate"
40
+ end
41
+
42
+ def runner_command
43
+ framework_version?("3") ? "script/rails runner" : "script/runner"
44
+ end
45
+ end
46
+ World(RailsCommandHelpers)
@@ -0,0 +1,19 @@
1
+ module HtmlSelectorsHelpers
2
+ # Maps a name to a selector. Used primarily by the
3
+ #
4
+ # When /^(.+) within (.+)$/ do |step, scope|
5
+ #
6
+ # step definitions in web_steps.rb
7
+ #
8
+ def selector_for(locator)
9
+ case locator
10
+ when "the page"
11
+ "html > body"
12
+ else
13
+ raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
14
+ "Now, go and add a mapping in #{__FILE__}"
15
+ end
16
+ end
17
+ end
18
+
19
+ World(HtmlSelectorsHelpers)
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 2.3.14"
6
+ gem "paperclip_database", :path=>"../"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 3.0.10"
6
+ gem "paperclip_database", :path=>"../"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 3.1.0"
6
+ gem "paperclip_database", :path=>"../"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,5 @@
1
+ Usage:
2
+
3
+ script/generate paperclip_database model attachment
4
+
5
+ This will create a migration that will add the proper table for the attachments.
@@ -0,0 +1,28 @@
1
+ class PaperclipDatabaseGenerator < Rails::Generator::NamedBase
2
+ attr_accessor :attachments, :migration_name
3
+
4
+ def initialize(args, options = {})
5
+ super
6
+ @class_name, @attachments = args[0], args[1..-1]
7
+ end
8
+
9
+ def manifest
10
+ file_name = generate_file_name
11
+ @migration_name = file_name.camelize
12
+ record do |m|
13
+ m.migration_template "paperclip_database_migration.rb.erb",
14
+ File.join('db', 'migrate'),
15
+ :migration_file_name => file_name
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def generate_file_name
22
+ debugger
23
+ names = attachments.map{|a| "#{class_name.underscore}_#{a.pluralize}" }
24
+ names = names[0..-2] + ["and", names[-1]] if names.length > 1
25
+ "create_#{names.join('_')}"
26
+ end
27
+
28
+ end
@@ -0,0 +1,17 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ <% attachments.each do |attachment| -%>
4
+ create_table :<%= class_name.underscore %>_<%= attachment.pluralize %> do |t|
5
+ t.integer :<%= class_name.underscore %>_id
6
+ t.string :style
7
+ t.binary :file_contents
8
+ end
9
+ <% end -%>
10
+ end
11
+
12
+ def self.down
13
+ <% attachments.each do |attachment| -%>
14
+ drop_table :<%= class_name.underscore %>_<%= attachment.pluralize %>
15
+ <% end -%>
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ <% attachments.each do |attachment| -%>
4
+ create_table :<%= name.underscore.camelize.tableize %>_<%= attachment.pluralize %> do |t|
5
+ t.integer :<%= name.underscore.camelize.tableize %>_id
6
+ t.string :style
7
+ t.binary :file_contents
8
+ end
9
+ end
10
+ <% end -%>
11
+
12
+ def self.down
13
+ <% attachments.each do |attachment| -%>
14
+ drop_table :<%= name.underscore.camelize.tableize %>_<%= attachment.pluralize %>
15
+ <% end -%>
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ The generator generates a database migration for the paperclip database storage
3
+
4
+ Example:
5
+ rails generate paperclip_database Class attachments
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,33 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ class PaperclipDatabaseGenerator < ActiveRecord::Generators::Base
4
+ desc "Create a migration to add database storage for the paperclip database storage." +
5
+ "The NAME argument is the name of your model, and the following " +
6
+ "arguments are the name of the attachments"
7
+
8
+ argument :attachment_names, :required => true, :type => :array, :desc => "The names of the attachment(s) to add.",
9
+ :banner => "attachment_one attachment_two attachment_three ..."
10
+
11
+ def self.source_root
12
+ @source_root ||= File.expand_path('../templates', __FILE__)
13
+ end
14
+
15
+ def generate_migration
16
+ migration_template "paperclip_database_migration.rb.erb", "db/migrate/#{migration_file_name}"
17
+ end
18
+
19
+ protected
20
+
21
+ def migration_name
22
+ "create_#{name.underscore}_#{attachment_names.map{|n| n.pluralize}.join('_and_')}"
23
+ end
24
+
25
+ def migration_file_name
26
+ "#{migration_name}.rb"
27
+ end
28
+
29
+ def migration_class_name
30
+ migration_name.camelize
31
+ end
32
+
33
+ end
@@ -0,0 +1,17 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ <% attachment_names.each do |attachment| -%>
4
+ create_table :<%= class_name.underscore %>_<%= attachment.pluralize %> do |t|
5
+ t.integer :<%= class_name.underscore %>_id
6
+ t.string :style
7
+ t.binary :file_contents
8
+ end
9
+ <% end -%>
10
+ end
11
+
12
+ def self.down
13
+ <% attachment_names.each do |attachment| -%>
14
+ drop_table :<%= class_name.underscore %>_<%= attachment.pluralize %>
15
+ <% end -%>
16
+ end
17
+ end
@@ -0,0 +1,198 @@
1
+ module Paperclip
2
+ module Storage
3
+ # Store files in a database.
4
+ #
5
+ # Usage is identical to the file system storage version, except:
6
+ #
7
+ # 1. In your model specify the "database" storage option; for example:
8
+ # has_attached_file :avatar, :storage => :database
9
+ #
10
+ # The files will be stored in a new database table named with the plural attachment name
11
+ # by default, "avatars" in this example.
12
+ #
13
+ # 2. You need to create this new storage table with at least these columns:
14
+ # - file_contents
15
+ # - style
16
+ # - the primary key for the parent model (e.g. user_id)
17
+ #
18
+ # Note the "binary" migration will not work for the LONGBLOG type in MySQL for the
19
+ # file_cotents column. You may need to craft a SQL statement for your migration,
20
+ # depending on which database server you are using. Here's an example migration for MySQL:
21
+ #
22
+ # create_table :avatars do |t|
23
+ # t.string :style
24
+ # t.integer :user_id
25
+ # t.timestamps
26
+ # end
27
+ # execute 'ALTER TABLE avatars ADD COLUMN file_contents LONGBLOB'
28
+ #
29
+ # You can optionally specify any storage table name you want as follows:
30
+ # has_attached_file :avatar, :storage => :database, :database_table => 'avatar_files'
31
+ #
32
+ # 3. By default, URLs will be set to this pattern:
33
+ # /:relative_root/:class/:attachment/:id?style=:style
34
+ #
35
+ # Example:
36
+ # /app-root-url/users/avatars/23?style=original
37
+ #
38
+ # The idea here is that to retrieve a file from the database storage, you will need some
39
+ # controller's code to be executed.
40
+ #
41
+ # Once you pick a controller to use for downloading, you can add this line
42
+ # to generate the download action for the default URL/action (the plural attachment name),
43
+ # "avatars" in this example:
44
+ # downloads_files_for :user, :avatar
45
+ #
46
+ # Or you can write a download method manually if there are security, logging or other
47
+ # requirements.
48
+ #
49
+ # If you prefer a different URL for downloading files you can specify that in the model; e.g.:
50
+ # has_attached_file :avatar, :storage => :database, :url => '/users/show_avatar/:id/:style'
51
+ #
52
+ # 4. Add a route for the download to the controller which will handle downloads, if necessary.
53
+ #
54
+ # The default URL, /:relative_root/:class/:attachment/:id?style=:style, will be matched by
55
+ # the default route: :controller/:action/:id
56
+ #
57
+ module Database
58
+
59
+ def self.extended(base)
60
+ base.instance_eval do
61
+ setup_paperclip_files_model
62
+ override_default_options base
63
+ end
64
+ Paperclip.interpolates(:database_path) do |attachment, style|
65
+ attachment.database_path(style)
66
+ end
67
+ Paperclip.interpolates(:relative_root) do |attachment, style|
68
+ begin
69
+ if ActionController::AbstractRequest.respond_to?(:relative_url_root)
70
+ relative_url_root = ActionController::AbstractRequest.relative_url_root
71
+ end
72
+ rescue NameError
73
+ end
74
+ if !relative_url_root && ActionController::Base.respond_to?(:relative_url_root)
75
+ ActionController::Base.relative_url_root
76
+ end
77
+ end
78
+
79
+ ActiveRecord::Base.logger.info("[paperclip] Database Storage Initalized.")
80
+ end
81
+
82
+ def setup_paperclip_files_model
83
+ #TODO: This fails when your model is in a namespace.
84
+ @paperclip_files = "#{instance.class.name.underscore}_#{name.to_s}_paperclip_files"
85
+ if !Object.const_defined?(@paperclip_files.classify)
86
+ @paperclip_file = Object.const_set(@paperclip_files.classify, Class.new(::ActiveRecord::Base))
87
+ else
88
+ @paperclip_file = Object.const_get(@paperclip_files.classify)
89
+ end
90
+ @database_table = @options[:database_table] || name.to_s.pluralize
91
+ @paperclip_file.set_table_name @database_table
92
+ case Rails::VERSION::STRING
93
+ when /^2/
94
+ @paperclip_file.named_scope :file_for, lambda {|style| { :conditions => ['style = ?', style] }}
95
+ else # 3.x
96
+ @paperclip_file.scope :file_for, lambda {|style| { :conditions => ['style = ?', style] }}
97
+ end
98
+ #FIXME: This fails when using set_table_name "<myname>" in your model
99
+ #FIXME: This should be fixed in ActiveRecord...
100
+ instance.class.has_many @paperclip_files, :foreign_key => instance.class.table_name.classify.underscore + '_id'
101
+
102
+ end
103
+ private :setup_paperclip_files_model
104
+
105
+ def override_default_options(base)
106
+ if @url == base.class.default_options[:url]
107
+ @url = ":relative_root/:class/:attachment/:id?style=:style"
108
+ end
109
+ @path = ":database_path"
110
+ end
111
+ private :override_default_options
112
+
113
+ def database_table
114
+ @database_table
115
+ end
116
+
117
+ def database_path(style)
118
+ paperclip_file = file_for(style)
119
+ if paperclip_file
120
+ "#{database_table}(id=#{paperclip_file.id},style=#{style.to_s})"
121
+ else
122
+ "#{database_table}(id=new,style=#{style.to_s})"
123
+ end
124
+ end
125
+
126
+ def exists?(style = default_style)
127
+ if original_filename
128
+ !file_for(style).nil?
129
+ else
130
+ false
131
+ end
132
+ end
133
+
134
+ # Returns representation of the data of the file assigned to the given
135
+ # style, in the format most representative of the current storage.
136
+ def to_file style = default_style
137
+ if @queued_for_write[style]
138
+ @queued_for_write[style]
139
+ elsif exists?(style)
140
+ tempfile = Tempfile.new instance_read(:file_name)
141
+ tempfile.write file_contents(style)
142
+ tempfile.flush
143
+ tempfile.rewind
144
+ tempfile
145
+ else
146
+ nil
147
+ end
148
+
149
+ end
150
+ alias_method :to_io, :to_file
151
+
152
+ def file_for(style)
153
+ db_result = instance.send("#{@paperclip_files}").send(:file_for, style.to_s).to_ary
154
+ raise RuntimeError, "More than one result for #{style}" if db_result.size > 1
155
+ db_result.first
156
+ end
157
+
158
+ def file_contents(style)
159
+ file_for(style).file_contents
160
+ end
161
+
162
+ def flush_writes
163
+ ActiveRecord::Base.logger.info("[paperclip] Writing files for #{name}")
164
+ @queued_for_write.each do |style, file|
165
+ paperclip_file = @paperclip_file.new
166
+ paperclip_file.file_contents = file.read
167
+ paperclip_file.style = style.to_s;
168
+ instance.send(@paperclip_files) << paperclip_file
169
+ end
170
+ @queued_for_write = {}
171
+ end
172
+
173
+ def flush_deletes #:nodoc:
174
+ ActiveRecord::Base.logger.info("[paperclip] Deleting files for #{name}")
175
+ @queued_for_delete.each do |path|
176
+ /id=([0-9]+)/.match(path)
177
+ @paperclip_file.destroy $1
178
+ end
179
+ @queued_for_delete = []
180
+ end
181
+
182
+ module ControllerClassMethods
183
+ def self.included(base)
184
+ base.extend(self)
185
+ end
186
+ def downloads_files_for(model, attachment, options = {})
187
+ define_method("#{attachment.to_s.pluralize}") do
188
+ model_record = Object.const_get(model.to_s.camelize.to_sym).find(params[:id])
189
+ style = params[:style] ? params[:style] : 'original'
190
+ send_data model_record.send(attachment).file_contents(style),
191
+ :filename => model_record.send("#{attachment}_file_name".to_sym),
192
+ :type => model_record.send("#{attachment}_content_type".to_sym)
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end