paperclip_database 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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