paperclip_database_myplaceonline 3.1.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 (44) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +57 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +15 -0
  6. data/Appraisals +71 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE.txt +26 -0
  9. data/README.md +126 -0
  10. data/Rakefile +42 -0
  11. data/features/basic_integration.feature +45 -0
  12. data/features/step_definitions/html_steps.rb +15 -0
  13. data/features/step_definitions/paperclip_database_steps.rb +0 -0
  14. data/features/step_definitions/rails_steps.rb +209 -0
  15. data/features/step_definitions/web_steps.rb +115 -0
  16. data/features/support/env.rb +15 -0
  17. data/features/support/fakeweb.rb +3 -0
  18. data/features/support/paths.rb +28 -0
  19. data/features/support/rails.rb +62 -0
  20. data/features/support/selectors.rb +19 -0
  21. data/gemfiles/rails42_paperclip4x.gemfile +11 -0
  22. data/gemfiles/rails42_paperclip5x.gemfile +11 -0
  23. data/gemfiles/rails42_paperclip6x.gemfile +11 -0
  24. data/gemfiles/rails50_paperclip4x.gemfile +11 -0
  25. data/gemfiles/rails50_paperclip5x.gemfile +11 -0
  26. data/gemfiles/rails50_paperclip6x.gemfile +12 -0
  27. data/gemfiles/rails51_paperclip6x.gemfile +12 -0
  28. data/gemfiles/rails52_paperclip6x.gemfile +12 -0
  29. data/lib/generators/paperclip_database/migration/USAGE +8 -0
  30. data/lib/generators/paperclip_database/migration/migration_generator.rb +44 -0
  31. data/lib/generators/paperclip_database/migration/templates/migration.rb.erb +20 -0
  32. data/lib/paperclip/storage/database.rb +243 -0
  33. data/lib/paperclip_database/version.rb +3 -0
  34. data/lib/paperclip_database.rb +3 -0
  35. data/paperclip_database.gemspec +37 -0
  36. data/rails/init.rb +3 -0
  37. data/spec/database.yml +3 -0
  38. data/spec/default_options_spec.rb +74 -0
  39. data/spec/fixtures/5k.png +0 -0
  40. data/spec/major_version_API_spec.rb +89 -0
  41. data/spec/namespaced_models_spec.rb +39 -0
  42. data/spec/single_table_inheritance_spec.rb +39 -0
  43. data/spec/spec_helper.rb +92 -0
  44. metadata +260 -0
@@ -0,0 +1,115 @@
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 (not )?see "([^"]*)"$/ do |negate, text|
106
+ if negate
107
+ expect(page).not_to have_content(text)
108
+ else
109
+ expect(page).to have_content(text)
110
+ end
111
+ end
112
+
113
+ Then /^show me the page$/ do
114
+ save_and_open_page
115
+ 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,62 @@
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 framework_major_version
35
+ framework_version.split(".").first.to_i
36
+ end
37
+
38
+ def new_application_command(app_name)
39
+ "rails new #{app_name} --skip-sprockets --skip-javascript --skip-bundle"
40
+ end
41
+
42
+ def generator_command
43
+ "rails generate"
44
+ end
45
+
46
+ def runner_command
47
+ "rails runner"
48
+ end
49
+ end
50
+
51
+ module PaperclipGemHelpers
52
+ def paperclip_version?(version_string)
53
+ paperclip_version =~ /^#{version_string}/
54
+ end
55
+
56
+ def paperclip_version
57
+ @paperclip_version = Gem::Specification.find_by_name('paperclip').version.to_s
58
+ end
59
+ end
60
+
61
+ World(RailsCommandHelpers)
62
+ World(PaperclipGemHelpers)
@@ -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,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 4.2.0"
6
+ gem "paperclip", "~> 4.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 4.2.0"
6
+ gem "paperclip", "~> 5.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 4.2.0"
6
+ gem "paperclip", "~> 6.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.0.0"
6
+ gem "paperclip", "~> 4.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.0.0"
6
+ gem "paperclip", "~> 5.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.0.0"
6
+ gem "paperclip", "~> 6.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+ gem "bootsnap", "~> 1.0", require: false
11
+
12
+ gemspec path: "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.1.0"
6
+ gem "paperclip", "~> 6.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+ gem "bootsnap", "~> 1.0", require: false
11
+
12
+ gemspec path: "../"
@@ -0,0 +1,12 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rails", "~> 5.2.0"
6
+ gem "paperclip", "~> 6.0"
7
+ gem "capybara"
8
+ gem "rspec"
9
+ gem "sqlite3", "~> 1.3.0"
10
+ gem "bootsnap", "~> 1.0", require: false
11
+
12
+ gemspec path: "../"
@@ -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_migration User attachment
6
+
7
+ This will create:
8
+ db/migrations/YYYYMMDDHHmmss_create_user_attachments.rb
@@ -0,0 +1,44 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module PaperclipDatabase
4
+ module Generators
5
+ class MigrationGenerator < ActiveRecord::Generators::Base
6
+ desc "Create a migration to add database storage for the paperclip database storage." +
7
+ "The NAME argument is the name of your model, and the following " +
8
+ "arguments are the name of the attachments"
9
+
10
+ argument :attachment_names,
11
+ :required => true,
12
+ :type => :array,
13
+ :desc => "The names of the attachment(s) to add.",
14
+ :banner => "attachment_one attachment_two attachment_three ..."
15
+
16
+ def self.source_root
17
+ @source_root ||= File.expand_path('../templates', __FILE__)
18
+ end
19
+
20
+ def generate_migration
21
+ migration_template "migration.rb.erb", "db/migrate/#{migration_file_name}", migration_version: migration_version
22
+ end
23
+
24
+ def migration_name
25
+ "create_#{name.underscore.tr('/', '_')}_#{attachment_names.map{|n| n.pluralize}.join('_and_')}"
26
+ end
27
+
28
+ def migration_file_name
29
+ "#{migration_name}.rb"
30
+ end
31
+
32
+ def migration_class_name
33
+ migration_name.camelize
34
+ end
35
+
36
+ def migration_version
37
+ if Rails.version.to_i >= 5
38
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
+ def self.up
3
+ <%
4
+ module_names = class_name.underscore.split('/')[0...-1]
5
+ -%>
6
+ <% attachment_names.each do |attachment| -%>
7
+ create_table :<%= (module_names +[attachment.pluralize]).join("_") %> do |t|
8
+ t.integer :<%= class_name.underscore.tr('/', '_') %>_id
9
+ t.string :style
10
+ t.binary :file_contents
11
+ end
12
+ <% end -%>
13
+ end
14
+
15
+ def self.down
16
+ <% attachment_names.each do |attachment| -%>
17
+ drop_table :<%= (module_names +[attachment.pluralize]).join("_") %>
18
+ <% end -%>
19
+ end
20
+ end
@@ -0,0 +1,243 @@
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 and whether or not deletion is done by cascading or not as follows:
30
+ # has_attached_file :avatar, :storage => :database, :database_table => 'avatar_files', :cascade_deletion => true
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_attachment_class
62
+ setup_paperclip_file_model
63
+ setup_paperclip_files_association
64
+ override_default_options base
65
+ end
66
+ Paperclip.interpolates(:database_path) do |attachment, style|
67
+ attachment.database_path(style)
68
+ end
69
+ Paperclip.interpolates(:relative_root) do |attachment, style|
70
+ begin
71
+ if ActionController::AbstractRequest.respond_to?(:relative_url_root)
72
+ relative_url_root = ActionController::AbstractRequest.relative_url_root
73
+ end
74
+ rescue NameError
75
+ end
76
+ if !relative_url_root && ActionController::Base.respond_to?(:relative_url_root)
77
+ ActionController::Base.relative_url_root
78
+ end
79
+ end
80
+
81
+ ActiveRecord::Base.logger.info("[paperclip] Database Storage Initalized.")
82
+ end
83
+
84
+ def setup_paperclip_files_association
85
+ @paperclip_files_association_name = @paperclip_file_model.name.demodulize.tableize
86
+ @database_table = @paperclip_file_model.table_name
87
+ #FIXME: This fails when using set_table_name "<myname>" in your model
88
+ #FIXME: This should be fixed in ActiveRecord...
89
+ instance.class.has_many(@paperclip_files_association_name.to_sym,
90
+ :class_name => @paperclip_file_model.name,
91
+ :foreign_key => instance.class.table_name.classify.underscore + '_id'
92
+ )
93
+ end
94
+ private :setup_paperclip_files_association
95
+
96
+ def setup_paperclip_file_model
97
+ class_name = "#{instance.class.table_name.singularize}_#{name.to_s}_paperclip_file".classify
98
+ if @attachment_class.const_defined?(class_name, false)
99
+ @paperclip_file_model = @attachment_class.const_get(class_name, false)
100
+ else
101
+ @paperclip_file_model = @attachment_class.const_set(class_name, Class.new(::ActiveRecord::Base))
102
+ @paperclip_file_model.table_name = @options[:database_table] || name.to_s.pluralize
103
+ @paperclip_file_model.validates_uniqueness_of :style, :scope => instance.class.table_name.classify.underscore + '_id'
104
+ case ActiveModel::VERSION::MAJOR
105
+ when 3, 4
106
+ @paperclip_file_model.scope :file_for, lambda {|style| @paperclip_file_model.where('style = ?', style) }
107
+ when 5,6,7,8
108
+ @paperclip_file_model.scope :file_for, lambda {|style| where('style = ?', style) }
109
+ else
110
+ raise "ActiveModel version #{ActiveModel::VERSION::STRING} is not supported (yet)"
111
+ end
112
+ end
113
+ end
114
+ private :setup_paperclip_file_model
115
+
116
+ def setup_attachment_class
117
+ instance.class.ancestors.each do |ancestor|
118
+ # Pick the top-most definition like
119
+ # Paperclip::AttachmentRegistry#definitions_for
120
+ names_for_ancestor = ancestor.attachment_definitions.keys rescue []
121
+ if names_for_ancestor.member?(name)
122
+ @attachment_class = ancestor
123
+ end
124
+ end
125
+ end
126
+ private :setup_attachment_class
127
+
128
+ def copy_to_local_file(style, dest_path)
129
+ File.open(dest_path, 'wb+'){|df| to_file(style).tap{|sf| File.copy_stream(sf, df); sf.close;sf.unlink} }
130
+ end
131
+
132
+ def override_default_options(base)
133
+ if @options[:url] == base.class.default_options[:url]
134
+ @options[:url] = ":relative_root/:class/:attachment/:id?style=:style"
135
+ end
136
+ @options[:path] = ":database_path"
137
+ end
138
+ private :override_default_options
139
+
140
+ def database_table
141
+ @database_table
142
+ end
143
+
144
+ def database_path(style)
145
+ paperclip_file = file_for(style)
146
+ if paperclip_file
147
+ "#{database_table}(id=#{paperclip_file.id},style=#{style.to_s})"
148
+ else
149
+ "#{database_table}(id=new,style=#{style.to_s})"
150
+ end
151
+ end
152
+
153
+ def exists?(style = default_style)
154
+ if original_filename
155
+ instance.send("#{@paperclip_files_association_name}").where(:style => style).exists?
156
+ else
157
+ false
158
+ end
159
+ end
160
+
161
+ # Returns representation of the data of the file assigned to the given
162
+ # style, in the format most representative of the current storage.
163
+ def to_file style = default_style
164
+ if @queued_for_write[style]
165
+ @queued_for_write[style]
166
+ elsif exists?(style)
167
+ tempfile = Tempfile.new instance_read(:file_name)
168
+ tempfile.binmode
169
+ tempfile.write file_contents(style)
170
+ tempfile.flush
171
+ tempfile.rewind
172
+ tempfile
173
+ else
174
+ nil
175
+ end
176
+
177
+ end
178
+ alias_method :to_io, :to_file
179
+
180
+ def files
181
+ instance.send("#{@paperclip_files_association_name}")
182
+ end
183
+
184
+ def file_for(style)
185
+ db_result = instance.send("#{@paperclip_files_association_name}").send(:file_for, style.to_s)
186
+ raise RuntimeError, "More than one result for #{style}" if db_result.size > 1
187
+ db_result.first
188
+ end
189
+
190
+ def file_contents(style = default_style)
191
+ file_for(style).file_contents
192
+ end
193
+
194
+ def flush_writes
195
+ ActiveRecord::Base.logger.info("[paperclip] Writing files for #{name}")
196
+ @queued_for_write.each do |style, file|
197
+ case ActiveModel::VERSION::MAJOR
198
+ when 3
199
+ paperclip_file = instance.send(@paperclip_files_association_name).send(:find_or_create_by_style, style.to_s)
200
+ when 4,5,6,7,8
201
+ paperclip_file = instance.send(@paperclip_files_association_name).send(:find_or_create_by, style: style.to_s)
202
+ else
203
+ raise "ActiveModel version #{ActiveModel::VERSION::STRING} is not supported (yet)"
204
+ end
205
+ paperclip_file.file_contents = file.read
206
+ paperclip_file.save!
207
+ instance.reload
208
+ end
209
+ @queued_for_write = {}
210
+ end
211
+
212
+ def flush_deletes #:nodoc:
213
+ ActiveRecord::Base.logger.info("[paperclip] Deleting files for #{name}")
214
+ @queued_for_delete.uniq! ##This is apparently necessary for paperclip v 3.x
215
+ @queued_for_delete.each do |path|
216
+ /id=([0-9]+)/.match(path)
217
+ if @options[:cascade_deletion] && !instance.class.exists?(instance.id)
218
+ raise RuntimeError, "Deletion has not been done by through cascading." if @paperclip_file_model.exists?($1)
219
+ else
220
+ @paperclip_file_model.destroy $1
221
+ end
222
+ end
223
+ @queued_for_delete = []
224
+ end
225
+
226
+ module ControllerClassMethods
227
+ def self.included(base)
228
+ base.extend(self)
229
+ end
230
+ def downloads_files_for(model, attachment, options = {})
231
+ define_method("#{attachment.to_s.pluralize}") do
232
+ #FIXME: Handling Namespaces
233
+ model_record = Object.const_get(model.to_s.camelize.to_sym, false).find(params[:id])
234
+ style = params[:style] ? params[:style] : 'original'
235
+ send_data model_record.send(attachment).file_contents(style),
236
+ :filename => model_record.send("#{attachment}_file_name".to_sym),
237
+ :type => model_record.send("#{attachment}_content_type".to_sym)
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,3 @@
1
+ module PaperclipDatabase
2
+ VERSION = "3.1.1" unless defined? PaperclipDatabase::VERSION
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'paperclip'
2
+ require 'paperclip/storage/database'
3
+ require 'paperclip_database/version'