paperclip 3.5.4 → 4.3.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +0 -6
- data/.hound.yml +1066 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +11 -17
- data/Appraisals +6 -14
- data/CONTRIBUTING.md +13 -8
- data/Gemfile +16 -3
- data/LICENSE +1 -3
- data/NEWS +167 -49
- data/README.md +294 -75
- data/RELEASING.md +17 -0
- data/Rakefile +6 -8
- data/features/basic_integration.feature +24 -6
- data/features/step_definitions/attachment_steps.rb +30 -22
- data/features/step_definitions/html_steps.rb +2 -2
- data/features/step_definitions/rails_steps.rb +44 -14
- data/features/step_definitions/web_steps.rb +1 -103
- data/features/support/env.rb +2 -2
- data/features/support/file_helpers.rb +2 -2
- data/features/support/fixtures/gemfile.txt +1 -1
- data/features/support/rails.rb +2 -1
- data/gemfiles/3.2.gemfile +14 -6
- data/gemfiles/4.1.gemfile +19 -0
- data/gemfiles/4.2.gemfile +19 -0
- data/lib/generators/paperclip/paperclip_generator.rb +0 -2
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
- data/lib/paperclip/attachment.rb +132 -38
- data/lib/paperclip/attachment_registry.rb +1 -1
- data/lib/paperclip/callbacks.rb +11 -1
- data/lib/paperclip/content_type_detector.rb +25 -22
- data/lib/paperclip/deprecations.rb +42 -0
- data/lib/paperclip/errors.rb +5 -0
- data/lib/paperclip/file_command_content_type_detector.rb +6 -8
- data/lib/paperclip/geometry_detector_factory.rb +3 -1
- data/lib/paperclip/geometry_parser_factory.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +10 -0
- data/lib/paperclip/interpolations/plural_cache.rb +6 -5
- data/lib/paperclip/interpolations.rb +25 -12
- data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
- data/lib/paperclip/io_adapters/attachment_adapter.rb +4 -4
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +5 -10
- data/lib/paperclip/io_adapters/stringio_adapter.rb +6 -10
- data/lib/paperclip/io_adapters/uri_adapter.rb +30 -11
- data/lib/paperclip/locales/de.yml +18 -0
- data/lib/paperclip/locales/en.yml +1 -0
- data/lib/paperclip/locales/es.yml +18 -0
- data/lib/paperclip/locales/ja.yml +18 -0
- data/lib/paperclip/locales/pt-BR.yml +18 -0
- data/lib/paperclip/locales/zh-CN.yml +18 -0
- data/lib/paperclip/locales/zh-HK.yml +18 -0
- data/lib/paperclip/locales/zh-TW.yml +18 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
- data/lib/paperclip/media_type_spoof_detector.rb +89 -0
- data/lib/paperclip/processor.rb +0 -37
- data/lib/paperclip/processor_helpers.rb +50 -0
- data/lib/paperclip/rails_environment.rb +25 -0
- data/lib/paperclip/schema.rb +10 -2
- data/lib/paperclip/storage/filesystem.rb +1 -1
- data/lib/paperclip/storage/fog.rb +18 -7
- data/lib/paperclip/storage/s3.rb +53 -22
- data/lib/paperclip/style.rb +8 -2
- data/lib/paperclip/tempfile_factory.rb +5 -1
- data/lib/paperclip/thumbnail.rb +12 -10
- data/lib/paperclip/url_generator.rb +11 -3
- data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
- data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +11 -3
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
- data/lib/paperclip/validators.rb +10 -3
- data/lib/paperclip/version.rb +1 -1
- data/lib/paperclip.rb +26 -8
- data/lib/tasks/paperclip.rake +17 -2
- data/paperclip.gemspec +16 -14
- data/shoulda_macros/paperclip.rb +0 -1
- data/spec/paperclip/attachment_definitions_spec.rb +13 -0
- data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +20 -21
- data/spec/paperclip/attachment_registry_spec.rb +130 -0
- data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +438 -397
- data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +16 -19
- data/spec/paperclip/deprecations_spec.rb +65 -0
- data/{test/file_command_content_type_detector_test.rb → spec/paperclip/file_command_content_type_detector_spec.rb} +5 -6
- data/spec/paperclip/filename_cleaner_spec.rb +14 -0
- data/spec/paperclip/geometry_detector_spec.rb +39 -0
- data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
- data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +50 -52
- data/spec/paperclip/glue_spec.rb +44 -0
- data/{test/has_attached_file_test.rb → spec/paperclip/has_attached_file_spec.rb} +45 -28
- data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +134 -126
- data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +70 -46
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
- data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +27 -29
- data/{test/io_adapters/data_uri_adapter_test.rb → spec/paperclip/io_adapters/data_uri_adapter_spec.rb} +26 -17
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
- data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +36 -40
- data/{test/io_adapters/http_url_proxy_adapter_test.rb → spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb} +31 -29
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
- data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
- data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +10 -7
- data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +20 -17
- data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +41 -41
- data/{test/io_adapters/uri_adapter_test.rb → spec/paperclip/io_adapters/uri_adapter_spec.rb} +53 -28
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -0
- data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
- data/spec/paperclip/media_type_spoof_detector_spec.rb +79 -0
- data/spec/paperclip/meta_class_spec.rb +30 -0
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
- data/{test/paperclip_test.rb → spec/paperclip/paperclip_spec.rb} +53 -48
- data/spec/paperclip/plural_cache_spec.rb +37 -0
- data/spec/paperclip/processor_helpers_spec.rb +57 -0
- data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +5 -5
- data/spec/paperclip/rails_environment_spec.rb +33 -0
- data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
- data/spec/paperclip/schema_spec.rb +248 -0
- data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
- data/spec/paperclip/storage/fog_spec.rb +535 -0
- data/spec/paperclip/storage/s3_live_spec.rb +182 -0
- data/spec/paperclip/storage/s3_spec.rb +1526 -0
- data/spec/paperclip/style_spec.rb +255 -0
- data/spec/paperclip/tempfile_factory_spec.rb +33 -0
- data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +123 -107
- data/spec/paperclip/url_generator_spec.rb +211 -0
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
- data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +20 -20
- data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +65 -58
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
- data/spec/paperclip/validators_spec.rb +164 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/assertions.rb +71 -0
- data/spec/support/deprecations.rb +9 -0
- data/spec/support/fake_model.rb +25 -0
- data/spec/support/fake_rails.rb +12 -0
- data/spec/support/fixtures/empty.html +1 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/fixtures/spaced file.jpg +0 -0
- data/spec/support/matchers/accept.rb +5 -0
- data/spec/support/matchers/exist.rb +5 -0
- data/spec/support/matchers/have_column.rb +23 -0
- data/spec/support/model_reconstruction.rb +60 -0
- data/spec/support/rails_helpers.rb +7 -0
- data/spec/support/test_data.rb +13 -0
- data/spec/support/version_helper.rb +9 -0
- metadata +334 -219
- data/RUNNING_TESTS.md +0 -4
- data/gemfiles/3.0.gemfile +0 -11
- data/gemfiles/3.1.gemfile +0 -11
- data/gemfiles/4.0.gemfile +0 -11
- data/test/attachment_definitions_test.rb +0 -12
- data/test/attachment_registry_test.rb +0 -88
- data/test/filename_cleaner_test.rb +0 -14
- data/test/generator_test.rb +0 -84
- data/test/geometry_detector_test.rb +0 -24
- data/test/helper.rb +0 -232
- data/test/io_adapters/abstract_adapter_test.rb +0 -58
- data/test/io_adapters/empty_string_adapter_test.rb +0 -18
- data/test/io_adapters/identity_adapter_test.rb +0 -8
- data/test/matchers/have_attached_file_matcher_test.rb +0 -24
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -110
- data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -69
- data/test/matchers/validate_attachment_size_matcher_test.rb +0 -86
- data/test/meta_class_test.rb +0 -32
- data/test/paperclip_missing_attachment_styles_test.rb +0 -90
- data/test/plural_cache_test.rb +0 -36
- data/test/schema_test.rb +0 -200
- data/test/storage/fog_test.rb +0 -473
- data/test/storage/s3_live_test.rb +0 -179
- data/test/storage/s3_test.rb +0 -1356
- data/test/style_test.rb +0 -213
- data/test/support/mock_model.rb +0 -2
- data/test/tempfile_factory_test.rb +0 -17
- data/test/url_generator_test.rb +0 -187
- data/test/validators/attachment_content_type_validator_test.rb +0 -324
- data/test/validators_test.rb +0 -61
- /data/{test → spec}/database.yml +0 -0
- /data/{test → spec/support}/fixtures/12k.png +0 -0
- /data/{test → spec/support}/fixtures/50x50.png +0 -0
- /data/{test → spec/support}/fixtures/5k.png +0 -0
- /data/{test → spec/support}/fixtures/animated +0 -0
- /data/{test → spec/support}/fixtures/animated.gif +0 -0
- /data/{test → spec/support}/fixtures/animated.unknown +0 -0
- /data/{test → spec/support}/fixtures/bad.png +0 -0
- /data/{test → spec/support}/fixtures/fog.yml +0 -0
- /data/{test → spec/support}/fixtures/rotated.jpg +0 -0
- /data/{test → spec/support}/fixtures/s3.yml +0 -0
- /data/{test → spec/support}/fixtures/spaced file.png +0 -0
- /data/{test → spec/support}/fixtures/text.txt +0 -0
- /data/{test → spec/support}/fixtures/twopage.pdf +0 -0
- /data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
- /data/{test → spec}/support/mock_attachment.rb +0 -0
- /data/{test → spec}/support/mock_interpolator.rb +0 -0
- /data/{test → spec}/support/mock_url_generator_builder.rb +0 -0
data/README.md
CHANGED
@@ -1,7 +1,46 @@
|
|
1
1
|
Paperclip
|
2
2
|
=========
|
3
3
|
|
4
|
-
[![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.
|
4
|
+
[![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.svg?branch=master)](http://travis-ci.org/thoughtbot/paperclip) [![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.svg?travis)](https://gemnasium.com/thoughtbot/paperclip) [![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.svg)](https://codeclimate.com/github/thoughtbot/paperclip) [![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.svg)](http://inch-ci.org/github/thoughtbot/paperclip) [![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master)
|
5
|
+
|
6
|
+
- [Requirements](#requirements)
|
7
|
+
- [Ruby on Rails](#ruby-and-rails)
|
8
|
+
- [Image Processor](#image-processor)
|
9
|
+
- [file](#file)
|
10
|
+
- [Installation](#installation)
|
11
|
+
- [Quick Start](#quick-start)
|
12
|
+
- [Models](#models)
|
13
|
+
- [Migrations](#migrations)
|
14
|
+
- [Edit and New Views](#edit-and-new-views)
|
15
|
+
- [Edit and New Views with Simple Form](#edit-and-new-views-with-simple-form)
|
16
|
+
- [Controller](#controller)
|
17
|
+
- [Show View](#show-view)
|
18
|
+
- [Deleting an Attachment](#deleting-an-attachment)
|
19
|
+
- [Usage](#usage)
|
20
|
+
- [Validations](#validations)
|
21
|
+
- [Security Validations](#security-validations)
|
22
|
+
- [Defaults](#defaults)
|
23
|
+
- [Migrations](#migrations-1)
|
24
|
+
- [Table Definition](#table-definition)
|
25
|
+
- [Schema Definition](#schema-definition)
|
26
|
+
- [Vintage Syntax](#vintage-syntax)
|
27
|
+
- [Storage](#storage)
|
28
|
+
- [Understanding Storage](#understanding-storage)
|
29
|
+
- [Post Processing](#post-processing)
|
30
|
+
- [Events](#events)
|
31
|
+
- [URI Obfuscation](#uri-obfuscation)
|
32
|
+
- [MD5 Checksum / Fingerprint](#md5-checksum--fingerprint)
|
33
|
+
- [File Preservation for Soft-Delete](#file-preservation-for-soft-delete)
|
34
|
+
- [Custom Attachment Processors](#custom-attachment-processors)
|
35
|
+
- [Dynamic Configuration](#dynamic-configuration)
|
36
|
+
- [Dynamic Styles](#dynamic-styles)
|
37
|
+
- [Dynamic Processors](#dynamic-processors)
|
38
|
+
- [Logging](#logging)
|
39
|
+
- [Deployment](#deployment)
|
40
|
+
- [Testing](#testing)
|
41
|
+
- [Contributing](#contributing)
|
42
|
+
- [License](#license)
|
43
|
+
- [About thoughtbot](#about-thoughtbot)
|
5
44
|
|
6
45
|
Paperclip is intended as an easy file attachment library for Active Record. The
|
7
46
|
intent behind it was to keep setup as easy as possible and to treat files as
|
@@ -20,13 +59,14 @@ more detailed options.
|
|
20
59
|
|
21
60
|
The complete [RDoc](http://rdoc.info/gems/paperclip) is online.
|
22
61
|
|
62
|
+
---
|
23
63
|
|
24
64
|
Requirements
|
25
65
|
------------
|
26
66
|
|
27
67
|
### Ruby and Rails
|
28
68
|
|
29
|
-
Paperclip now requires Ruby version **>=
|
69
|
+
Paperclip now requires Ruby version **>= 2.0.0** and Rails version **3.2, >= 4.1** (Only if you're going to use Paperclip with Ruby on Rails.)
|
30
70
|
|
31
71
|
If you're still on Ruby 1.8.7 or Ruby on Rails 2.3.x, you can still use Paperclip 2.7.x with your project. Also, everything in this README might not apply to your version of Paperclip, and you should read [the README for version 2.7](http://rubydoc.info/gems/paperclip/2.7.0) instead.
|
32
72
|
|
@@ -51,10 +91,57 @@ If you're on Mac OS X, you'll want to run the following with Homebrew:
|
|
51
91
|
brew install imagemagick
|
52
92
|
|
53
93
|
If you are dealing with pdf uploads or running the test suite, you'll also need
|
54
|
-
|
94
|
+
to install GhostScript. On Mac OS X, you can also install that using Homebrew:
|
55
95
|
|
56
96
|
brew install gs
|
57
97
|
|
98
|
+
If you're on Ubuntu, you'll want to run the following with apt-get:
|
99
|
+
|
100
|
+
sudo apt-get install imagemagick -y
|
101
|
+
|
102
|
+
If you're on Ubuntu (or any Debian base Linux distribution), you'll want to run the following with apt-get:
|
103
|
+
|
104
|
+
sudo apt-get install imagemagick -y
|
105
|
+
|
106
|
+
### `file`
|
107
|
+
|
108
|
+
The Unix [`file` command](http://en.wikipedia.org/wiki/File_(command)) is required for content-type checking.
|
109
|
+
This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit),
|
110
|
+
so Windows users must make sure that the devkit is installed and added to the system `PATH`.
|
111
|
+
|
112
|
+
**Manual Installation**
|
113
|
+
|
114
|
+
If you're using Windows 7+ as a development environment, you may need to install the `file.exe` application manually. The `file spoofing` system in Paperclip 4+ relies on this; if you don't have it working, you'll receive `Validation failed: Upload file has an extension that does not match its contents.` errors.
|
115
|
+
|
116
|
+
To manually install, you should perform the following:
|
117
|
+
|
118
|
+
> **Download & install `file` from [this URL](http://gnuwin32.sourceforge.net/packages/file.htm)**
|
119
|
+
|
120
|
+
To test, you can use the image below:
|
121
|
+
![untitled](https://cloud.githubusercontent.com/assets/1104431/4524452/a1f8cce4-4d44-11e4-872e-17adb96f79c9.png)
|
122
|
+
|
123
|
+
Next, you need to integrate with your environment - preferably through the `PATH` variable, or by changing your `config/environments/development.rb` file
|
124
|
+
|
125
|
+
**PATH**
|
126
|
+
|
127
|
+
1. Click "Start"
|
128
|
+
2. On "Computer", right-click and select "Properties"
|
129
|
+
3. In Properties, select "Advanced System Settings"
|
130
|
+
4. Click the "Environment Variables" button
|
131
|
+
5. Locate the "PATH" var - at the end, add the path to your newly installed `file.exe` (typically `C:\Program Files (x86)\GnuWin32\bin`)
|
132
|
+
6. Restart any CMD shells you have open & see if it works
|
133
|
+
|
134
|
+
OR
|
135
|
+
|
136
|
+
**Environment**
|
137
|
+
|
138
|
+
1. Open `config/environments/development.rb`
|
139
|
+
2. Add the following line: `Paperclip.options[:command_path] = 'C:\Program Files (x86)\GnuWin32\bin'`
|
140
|
+
3. Restart your Rails server
|
141
|
+
|
142
|
+
Either of these methods will give your Rails setup access to the `file.exe` functionality, thus providing the ability to check the contents of a file (fixing the spoofing problem)
|
143
|
+
|
144
|
+
---
|
58
145
|
|
59
146
|
Installation
|
60
147
|
------------
|
@@ -64,13 +151,7 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
|
|
64
151
|
Include the gem in your Gemfile:
|
65
152
|
|
66
153
|
```ruby
|
67
|
-
gem "paperclip", "~> 3
|
68
|
-
```
|
69
|
-
|
70
|
-
If you're still using Rails 2.3.x, you should do this instead:
|
71
|
-
|
72
|
-
```ruby
|
73
|
-
gem "paperclip", "~> 2.7"
|
154
|
+
gem "paperclip", "~> 4.3"
|
74
155
|
```
|
75
156
|
|
76
157
|
Or, if you want to get the latest, you can get master from the main paperclip repository:
|
@@ -93,6 +174,8 @@ class ModuleName < ActiveRecord::Base
|
|
93
174
|
end
|
94
175
|
```
|
95
176
|
|
177
|
+
---
|
178
|
+
|
96
179
|
Quick Start
|
97
180
|
-----------
|
98
181
|
|
@@ -104,6 +187,7 @@ Quick Start
|
|
104
187
|
class User < ActiveRecord::Base
|
105
188
|
attr_accessible :avatar
|
106
189
|
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
|
190
|
+
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
|
107
191
|
end
|
108
192
|
```
|
109
193
|
|
@@ -112,6 +196,7 @@ end
|
|
112
196
|
```ruby
|
113
197
|
class User < ActiveRecord::Base
|
114
198
|
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
|
199
|
+
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
|
115
200
|
end
|
116
201
|
```
|
117
202
|
|
@@ -119,17 +204,17 @@ end
|
|
119
204
|
|
120
205
|
```ruby
|
121
206
|
class AddAvatarColumnsToUsers < ActiveRecord::Migration
|
122
|
-
def
|
207
|
+
def up
|
123
208
|
add_attachment :users, :avatar
|
124
209
|
end
|
125
210
|
|
126
|
-
def
|
211
|
+
def down
|
127
212
|
remove_attachment :users, :avatar
|
128
213
|
end
|
129
214
|
end
|
130
215
|
```
|
131
216
|
|
132
|
-
(Or you can use migration generator: `rails generate paperclip user avatar`)
|
217
|
+
(Or you can use the Rails migration generator: `rails generate paperclip user avatar`)
|
133
218
|
|
134
219
|
### Edit and New Views
|
135
220
|
|
@@ -139,6 +224,13 @@ end
|
|
139
224
|
<% end %>
|
140
225
|
```
|
141
226
|
|
227
|
+
### Edit and New Views with Simple Form
|
228
|
+
```erb
|
229
|
+
<%= simple_form_for @user, url: users_path do |form| %>
|
230
|
+
<%= form.input :avatar, as: :file %>
|
231
|
+
<% end %>
|
232
|
+
```
|
233
|
+
|
142
234
|
### Controller
|
143
235
|
|
144
236
|
**Rails 3**
|
@@ -182,14 +274,15 @@ Set the attribute to `nil` and save.
|
|
182
274
|
@user.avatar = nil
|
183
275
|
@user.save
|
184
276
|
```
|
277
|
+
---
|
185
278
|
|
186
279
|
Usage
|
187
280
|
-----
|
188
281
|
|
189
|
-
The basics of
|
282
|
+
The basics of Paperclip are quite simple: Declare that your model has an
|
190
283
|
attachment with the `has_attached_file` method, and give it a name.
|
191
284
|
|
192
|
-
Paperclip will wrap up
|
285
|
+
Paperclip will wrap up to four attributes (all prefixed with that attachment's name,
|
193
286
|
so you can have multiple attachments per model if you wish) and give them a
|
194
287
|
friendly front end. These attributes are:
|
195
288
|
|
@@ -198,11 +291,11 @@ friendly front end. These attributes are:
|
|
198
291
|
* `<attachment>_content_type`
|
199
292
|
* `<attachment>_updated_at`
|
200
293
|
|
201
|
-
By default, only `<attachment>_file_name` is required for
|
294
|
+
By default, only `<attachment>_file_name` is required for Paperclip to operate.
|
202
295
|
You'll need to add `<attachment>_content_type` in case you want to use content type
|
203
296
|
validation.
|
204
297
|
|
205
|
-
More information about the options to `has_attached_file` is available in the
|
298
|
+
More information about the options passed to `has_attached_file` is available in the
|
206
299
|
documentation of [`Paperclip::ClassMethods`](http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods).
|
207
300
|
|
208
301
|
Validations
|
@@ -219,6 +312,8 @@ Example Usage:
|
|
219
312
|
```ruby
|
220
313
|
validates :avatar, :attachment_presence => true
|
221
314
|
validates_with AttachmentPresenceValidator, :attributes => :avatar
|
315
|
+
validates_with AttachmentSizeValidator, :attributes => :avatar, :less_than => 1.megabytes
|
316
|
+
|
222
317
|
```
|
223
318
|
|
224
319
|
Validators can also be defined using the old helper style:
|
@@ -237,12 +332,12 @@ Lastly, you can also define multiple validations on a single attachment using `v
|
|
237
332
|
|
238
333
|
```ruby
|
239
334
|
validates_attachment :avatar, :presence => true,
|
240
|
-
:content_type => { :content_type => "image/
|
335
|
+
:content_type => { :content_type => "image/jpeg" },
|
241
336
|
:size => { :in => 0..10.kilobytes }
|
242
337
|
```
|
243
338
|
|
244
|
-
_NOTE: Post
|
245
|
-
according to the validations. Your callbacks and processors will
|
339
|
+
_NOTE: Post-processing will not even **start** if the attachment is not valid
|
340
|
+
according to the validations. Your callbacks and processors will **only** be
|
246
341
|
called with valid attachments._
|
247
342
|
|
248
343
|
```ruby
|
@@ -296,17 +391,69 @@ image-y ones:
|
|
296
391
|
|
297
392
|
```ruby
|
298
393
|
validates_attachment :avatar,
|
299
|
-
:content_type => { :content_type => ["image/
|
394
|
+
:content_type => { :content_type => ["image/jpeg", "image/gif", "image/png"] }
|
300
395
|
```
|
301
396
|
|
302
397
|
`Paperclip::ContentTypeDetector` will attempt to match a file's extension to an
|
303
398
|
inferred content_type, regardless of the actual contents of the file.
|
304
399
|
|
400
|
+
---
|
401
|
+
|
402
|
+
Security Validations
|
403
|
+
====================
|
404
|
+
|
405
|
+
Thanks to a report from [Egor Homakov](http://homakov.blogspot.com/) we have
|
406
|
+
taken steps to prevent people from spoofing Content-Types and getting data
|
407
|
+
you weren't expecting onto your server.
|
408
|
+
|
409
|
+
NOTE: Starting at version 4.0.0, all attachments are *required* to include a
|
410
|
+
content_type validation, a file_name validation, or to explicitly state that
|
411
|
+
they're not going to have either. *Paperclip will raise an error* if you do not
|
412
|
+
do this.
|
413
|
+
|
414
|
+
```ruby
|
415
|
+
class ActiveRecord::Base
|
416
|
+
has_attached_file :avatar
|
417
|
+
# Validate content type
|
418
|
+
validates_attachment_content_type :avatar, :content_type => /\Aimage/
|
419
|
+
# Validate filename
|
420
|
+
validates_attachment_file_name :avatar, :matches => [/png\Z/, /jpe?g\Z/]
|
421
|
+
# Explicitly do not validate
|
422
|
+
do_not_validate_attachment_file_type :avatar
|
423
|
+
end
|
424
|
+
```
|
425
|
+
|
426
|
+
This keeps Paperclip secure-by-default, and will prevent people trying to mess
|
427
|
+
with your filesystem.
|
428
|
+
|
429
|
+
NOTE: Also starting at version 4.0.0, Paperclip has another validation that
|
430
|
+
cannot be turned off. This validation will prevent content type spoofing. That
|
431
|
+
is, uploading a PHP document (for example) as part of the EXIF tags of a
|
432
|
+
well-formed JPEG. This check is limited to the media type (the first part of the
|
433
|
+
MIME type, so, 'text' in `text/plain`). This will prevent HTML documents from
|
434
|
+
being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a
|
435
|
+
`.jpg` extension. This validation will only add validation errors to the form. It
|
436
|
+
will not cause errors to be raised.
|
437
|
+
|
438
|
+
This can sometimes cause false validation errors in applications that use custom
|
439
|
+
file extensions. In these cases you may wish to add your custom extension to the
|
440
|
+
list of file extensions allowed for your MIME type configured by the `mime-types`
|
441
|
+
gem:
|
442
|
+
|
443
|
+
```ruby
|
444
|
+
# Allow ".foo" as an extension for files with the MIME type "text/plain".
|
445
|
+
text_plain = MIME::Types["text/plain"].first
|
446
|
+
text_plain.extensions << "foo"
|
447
|
+
MIME::Types.index_extensions text_plain
|
448
|
+
```
|
449
|
+
|
450
|
+
---
|
451
|
+
|
305
452
|
Defaults
|
306
453
|
--------
|
307
|
-
Global defaults for all your
|
454
|
+
Global defaults for all your Paperclip attachments can be defined by changing the Paperclip::Attachment.default_options Hash. This can be useful for setting your default storage settings per example so you won't have to define them in every `has_attached_file` definition.
|
308
455
|
|
309
|
-
If you're using Rails you can define a Hash with default options in config/application.rb or in any of the config/environments/*.rb files on config.paperclip_defaults
|
456
|
+
If you're using Rails, you can define a Hash with default options in `config/application.rb` or in any of the `config/environments/*.rb` files on config.paperclip_defaults. These will get merged into `Paperclip::Attachment.default_options` as your Rails app boots. An example:
|
310
457
|
|
311
458
|
```ruby
|
312
459
|
module YourApp
|
@@ -318,7 +465,7 @@ module YourApp
|
|
318
465
|
end
|
319
466
|
```
|
320
467
|
|
321
|
-
Another option is to directly modify the Paperclip::Attachment.default_options Hash
|
468
|
+
Another option is to directly modify the `Paperclip::Attachment.default_options` Hash - this method works for non-Rails applications or is an option if you prefer to place the Paperclip default settings in an initializer.
|
322
469
|
|
323
470
|
An example Rails initializer would look something like this:
|
324
471
|
|
@@ -328,29 +475,36 @@ Paperclip::Attachment.default_options[:fog_credentials] = {:provider => "Local",
|
|
328
475
|
Paperclip::Attachment.default_options[:fog_directory] = ""
|
329
476
|
Paperclip::Attachment.default_options[:fog_host] = "http://localhost:3000"
|
330
477
|
```
|
478
|
+
---
|
331
479
|
|
332
480
|
Migrations
|
333
481
|
----------
|
334
482
|
|
335
|
-
Paperclip defines several migration methods which can be used to create necessary columns in your
|
336
|
-
model. There are two types of
|
483
|
+
Paperclip defines several migration methods which can be used to create the necessary columns in your
|
484
|
+
model. There are two types of helper methods to aid in this, as follows:
|
485
|
+
|
486
|
+
### Add Attachment Column To A Table
|
337
487
|
|
338
|
-
|
488
|
+
The `attachment` helper can be used when creating a table:
|
339
489
|
|
340
490
|
```ruby
|
341
|
-
class
|
342
|
-
def
|
491
|
+
class CreateUsersWithAttachments < ActiveRecord::Migration
|
492
|
+
def up
|
343
493
|
create_table :users do |t|
|
344
494
|
t.attachment :avatar
|
345
495
|
end
|
496
|
+
|
497
|
+
# This is assuming you are only using the users table for Paperclip attachment. Drop with care!
|
498
|
+
def down
|
499
|
+
drop_table :users
|
346
500
|
end
|
347
501
|
end
|
348
502
|
```
|
349
503
|
|
350
|
-
|
504
|
+
You can also use the `change` method, instead of the `up`/`down` combination above, as shown below:
|
351
505
|
|
352
506
|
```ruby
|
353
|
-
class
|
507
|
+
class CreateUsersWithAttachments < ActiveRecord::Migration
|
354
508
|
def change
|
355
509
|
create_table :users do |t|
|
356
510
|
t.attachment :avatar
|
@@ -361,22 +515,24 @@ end
|
|
361
515
|
|
362
516
|
### Schema Definition
|
363
517
|
|
518
|
+
Alternatively, the `add_attachment` and `remove_attachment` methods can be used to add new Paperclip columns to an existing table:
|
519
|
+
|
364
520
|
```ruby
|
365
|
-
class
|
366
|
-
def
|
521
|
+
class AddAttachmentColumnsToUsers < ActiveRecord::Migration
|
522
|
+
def up
|
367
523
|
add_attachment :users, :avatar
|
368
524
|
end
|
369
525
|
|
370
|
-
def
|
526
|
+
def down
|
371
527
|
remove_attachment :users, :avatar
|
372
528
|
end
|
373
529
|
end
|
374
530
|
```
|
375
531
|
|
376
|
-
|
532
|
+
Or you can do this with the `change` method:
|
377
533
|
|
378
534
|
```ruby
|
379
|
-
class
|
535
|
+
class AddAttachmentColumnsToUsers < ActiveRecord::Migration
|
380
536
|
def change
|
381
537
|
add_attachment :users, :avatar
|
382
538
|
end
|
@@ -385,9 +541,11 @@ end
|
|
385
541
|
|
386
542
|
### Vintage syntax
|
387
543
|
|
388
|
-
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`)
|
544
|
+
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) is still supported in
|
389
545
|
Paperclip 3.x, but you're advised to update those migration files to use this new syntax.
|
390
546
|
|
547
|
+
---
|
548
|
+
|
391
549
|
Storage
|
392
550
|
-------
|
393
551
|
|
@@ -422,7 +580,7 @@ You may also choose to store your files using Amazon's S3 service. To do so, inc
|
|
422
580
|
the `aws-sdk` gem in your Gemfile:
|
423
581
|
|
424
582
|
```ruby
|
425
|
-
gem 'aws-sdk', '~> 1.
|
583
|
+
gem 'aws-sdk', '~> 1.6'
|
426
584
|
```
|
427
585
|
|
428
586
|
And then you can specify using S3 from `has_attached_file`.
|
@@ -436,17 +594,20 @@ both the `:path` and `:url` options in order to make sure the files are unavaila
|
|
436
594
|
to the public. Both `:path` and `:url` allow the same set of interpolated
|
437
595
|
variables.
|
438
596
|
|
597
|
+
---
|
598
|
+
|
439
599
|
Post Processing
|
440
600
|
---------------
|
441
601
|
|
442
602
|
Paperclip supports an extensible selection of post-processors. When you define
|
443
603
|
a set of styles for an attachment, by default it is expected that those
|
444
|
-
"styles" are actually "thumbnails"
|
604
|
+
"styles" are actually "thumbnails." However, you can do much more than just
|
445
605
|
thumbnail images. By defining a subclass of Paperclip::Processor, you can
|
446
606
|
perform any processing you want on the files that are attached. Any file in
|
447
|
-
your Rails app's lib/paperclip
|
448
|
-
|
449
|
-
processor with the
|
607
|
+
your Rails app's `lib/paperclip` and `lib/paperclip_processors` directories is
|
608
|
+
automatically loaded by Paperclip, allowing you to easily define custom
|
609
|
+
processors. You can specify a processor with the `:processors` option to
|
610
|
+
`has_attached_file`:
|
450
611
|
|
451
612
|
```ruby
|
452
613
|
has_attached_file :scan, :styles => { :text => { :quality => :better } },
|
@@ -459,21 +620,21 @@ more information about defining processors, see Paperclip::Processor.
|
|
459
620
|
|
460
621
|
The default processor is Paperclip::Thumbnail. For backwards compatibility
|
461
622
|
reasons, you can pass a single geometry string or an array containing a
|
462
|
-
geometry and a format
|
623
|
+
geometry and a format that the file will be converted to, like so:
|
463
624
|
|
464
625
|
```ruby
|
465
626
|
has_attached_file :avatar, :styles => { :thumb => ["32x32#", :png] }
|
466
627
|
```
|
467
628
|
|
468
|
-
This will convert the "thumb" style to a 32x32 square in
|
629
|
+
This will convert the "thumb" style to a 32x32 square in PNG format, regardless
|
469
630
|
of what was uploaded. If the format is not specified, it is kept the same (i.e.
|
470
|
-
|
631
|
+
JPGs will remain JPGs). For more information on the accepted style formats, see
|
471
632
|
[here](http://www.imagemagick.org/script/command-line-processing.php#geometry).
|
472
633
|
|
473
634
|
Multiple processors can be specified, and they will be invoked in the order
|
474
|
-
they are defined in the
|
635
|
+
they are defined in the `:processors` array. Each successive processor will
|
475
636
|
be given the result of the previous processor's execution. All processors will
|
476
|
-
receive the same parameters, which are
|
637
|
+
receive the same parameters, which are defined in the `:styles` hash.
|
477
638
|
For example, assuming we had this definition:
|
478
639
|
|
479
640
|
```ruby
|
@@ -482,18 +643,20 @@ has_attached_file :scan, :styles => { :text => { :quality => :better } },
|
|
482
643
|
```
|
483
644
|
|
484
645
|
then both the :rotator processor and the :ocr processor would receive the
|
485
|
-
options
|
646
|
+
options `{ :quality => :better }`. This parameter may not mean anything to one
|
486
647
|
or more or the processors, and they are expected to ignore it.
|
487
648
|
|
488
649
|
_NOTE: Because processors operate by turning the original attachment into the
|
489
650
|
styles, no processors will be run if there are no styles defined._
|
490
651
|
|
491
652
|
If you're interested in caching your thumbnail's width, height and size in the
|
492
|
-
database, take a look at the [paperclip-meta](https://github.com/
|
653
|
+
database, take a look at the [paperclip-meta](https://github.com/teeparham/paperclip-meta) gem.
|
493
654
|
|
494
655
|
Also, if you're interested in generating the thumbnail on-the-fly, you might want
|
495
656
|
to look into the [attachment_on_the_fly](https://github.com/drpentode/Attachment-on-the-Fly) gem.
|
496
657
|
|
658
|
+
---
|
659
|
+
|
497
660
|
Events
|
498
661
|
------
|
499
662
|
|
@@ -508,8 +671,8 @@ normal ActiveRecord callbacks as possible, so if you return false (specifically
|
|
508
671
|
will halt. Returning false in an `after_filter` will not halt anything, but you
|
509
672
|
can access the model and the attachment if necessary.
|
510
673
|
|
511
|
-
_NOTE: Post processing will not even
|
512
|
-
according to the validations. Your callbacks and processors will
|
674
|
+
_NOTE: Post processing will not even **start** if the attachment is not valid
|
675
|
+
according to the validations. Your callbacks and processors will **only** be
|
513
676
|
called with valid attachments._
|
514
677
|
|
515
678
|
```ruby
|
@@ -524,6 +687,8 @@ class Message < ActiveRecord::Base
|
|
524
687
|
end
|
525
688
|
```
|
526
689
|
|
690
|
+
---
|
691
|
+
|
527
692
|
URI Obfuscation
|
528
693
|
---------------
|
529
694
|
|
@@ -543,29 +708,44 @@ has_attached_file :avatar, {
|
|
543
708
|
The `:hash` interpolation will be replaced with a unique hash made up of whatever
|
544
709
|
is specified in `:hash_data`. The default value for `:hash_data` is `":class/:attachment/:id/:style/:updated_at"`.
|
545
710
|
|
546
|
-
`:hash_secret` is required
|
711
|
+
`:hash_secret` is required - an exception will be raised if `:hash` is used without `:hash_secret` present.
|
547
712
|
|
548
|
-
For more on this feature read the author's own explanation
|
713
|
+
For more on this feature, read [the author's own explanation](https://github.com/thoughtbot/paperclip/pull/416)
|
549
714
|
|
550
715
|
MD5 Checksum / Fingerprint
|
551
716
|
-------
|
552
717
|
|
553
|
-
|
718
|
+
An MD5 checksum of the original file assigned will be placed in the model if it
|
554
719
|
has an attribute named fingerprint. Following the user model migration example
|
555
|
-
above, the migration would look like the following
|
720
|
+
above, the migration would look like the following:
|
556
721
|
|
557
722
|
```ruby
|
558
723
|
class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration
|
559
|
-
def
|
724
|
+
def up
|
560
725
|
add_column :users, :avatar_fingerprint, :string
|
561
726
|
end
|
562
727
|
|
563
|
-
def
|
728
|
+
def down
|
564
729
|
remove_column :users, :avatar_fingerprint
|
565
730
|
end
|
566
731
|
end
|
567
732
|
```
|
568
733
|
|
734
|
+
File Preservation for Soft-Delete
|
735
|
+
-------
|
736
|
+
|
737
|
+
An option is available to preserve attachments in order to play nicely with soft-deleted models. (acts_as_paranoid, paranoia, etc.)
|
738
|
+
|
739
|
+
```ruby
|
740
|
+
has_attached_file :some_attachment, {
|
741
|
+
:preserve_files => "true",
|
742
|
+
}
|
743
|
+
```
|
744
|
+
|
745
|
+
This will prevent ```some_attachment``` from being wiped out when the model gets destroyed, so it will still exist when the object is restored later.
|
746
|
+
|
747
|
+
---
|
748
|
+
|
569
749
|
Custom Attachment Processors
|
570
750
|
-------
|
571
751
|
|
@@ -574,15 +754,16 @@ to inherit from `Paperclip::Processor` (see `lib/paperclip/processor.rb`).
|
|
574
754
|
For example, when `:styles` are specified for an image attachment, the
|
575
755
|
thumbnail processor (see `lib/paperclip/thumbnail.rb`) is loaded without having
|
576
756
|
to specify it as a `:processor` parameter to `has_attached_file`. When any
|
577
|
-
other processor is defined it must be called out in the `:processors`
|
757
|
+
other processor is defined, it must be called out in the `:processors`
|
578
758
|
parameter if it is to be applied to the attachment. The thumbnail processor
|
579
|
-
uses the
|
759
|
+
uses the ImageMagick `convert` command to do the work of resizing image
|
580
760
|
thumbnails. It would be easy to create a custom processor that watermarks
|
581
|
-
an image using
|
761
|
+
an image using ImageMagick's `composite` command. Following the
|
582
762
|
implementation pattern of the thumbnail processor would be a way to implement a
|
583
763
|
watermark processor. All kinds of attachment processors can be created;
|
584
764
|
a few utility examples would be compression and encryption processors.
|
585
765
|
|
766
|
+
---
|
586
767
|
|
587
768
|
Dynamic Configuration
|
588
769
|
---------------------
|
@@ -597,7 +778,7 @@ instances.
|
|
597
778
|
### Dynamic Styles:
|
598
779
|
|
599
780
|
Imagine a user model that had different styles based on the role of the user.
|
600
|
-
Perhaps some users are bosses (e.g. a User model instance responds to
|
781
|
+
Perhaps some users are bosses (e.g. a User model instance responds to `#boss?`)
|
601
782
|
and merit a bigger avatar thumbnail than regular users. The configuration to
|
602
783
|
determine what style parameters are to be used based on the user role might
|
603
784
|
look as follows where a boss will receive a `300x300` thumbnail otherwise a
|
@@ -623,10 +804,12 @@ processors, where a defined `watermark` processor is invoked after the
|
|
623
804
|
```ruby
|
624
805
|
class User < ActiveRecord::Base
|
625
806
|
has_attached_file :avatar, :processors => lambda { |instance| instance.processors }
|
626
|
-
attr_accessor :
|
807
|
+
attr_accessor :processors
|
627
808
|
end
|
628
809
|
```
|
629
810
|
|
811
|
+
---
|
812
|
+
|
630
813
|
Logging
|
631
814
|
----------
|
632
815
|
|
@@ -641,6 +824,8 @@ end
|
|
641
824
|
|
642
825
|
More information in the [rdocs](http://rdoc.info/github/thoughtbot/paperclip/Paperclip.options)
|
643
826
|
|
827
|
+
---
|
828
|
+
|
644
829
|
Deployment
|
645
830
|
----------
|
646
831
|
|
@@ -657,16 +842,22 @@ Here is an example for Capistrano:
|
|
657
842
|
```ruby
|
658
843
|
namespace :deploy do
|
659
844
|
desc "build missing paperclip styles"
|
660
|
-
task :build_missing_paperclip_styles
|
661
|
-
|
845
|
+
task :build_missing_paperclip_styles do
|
846
|
+
on roles(:app) do
|
847
|
+
within release_path do
|
848
|
+
with rails_env: fetch(:rails_env) do
|
849
|
+
execute :rake, "paperclip:refresh:missing_styles"
|
850
|
+
end
|
851
|
+
end
|
852
|
+
end
|
662
853
|
end
|
663
854
|
end
|
664
855
|
|
665
|
-
after("deploy:
|
856
|
+
after("deploy:compile_assets", "deploy:build_missing_paperclip_styles")
|
666
857
|
```
|
667
858
|
|
668
859
|
Now you don't have to remember to refresh thumbnails in production every time you add a new style.
|
669
|
-
Unfortunately it does not work with dynamic styles - it just ignores them.
|
860
|
+
Unfortunately, it does not work with dynamic styles - it just ignores them.
|
670
861
|
|
671
862
|
If you already have a working app and don't want `rake paperclip:refresh:missing_styles` to refresh old pictures, you need to tell
|
672
863
|
Paperclip about existing styles. Simply create a `paperclip_attachments.yml` file by hand. For example:
|
@@ -699,6 +890,8 @@ Then in `RAILS_ROOT/public/system/paperclip_attachments.yml`:
|
|
699
890
|
- :thumb
|
700
891
|
```
|
701
892
|
|
893
|
+
---
|
894
|
+
|
702
895
|
Testing
|
703
896
|
-------
|
704
897
|
|
@@ -722,9 +915,29 @@ else
|
|
722
915
|
end
|
723
916
|
```
|
724
917
|
|
725
|
-
The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or
|
918
|
+
The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or a
|
726
919
|
similar mechanism for whichever parallel testing library you use.
|
727
920
|
|
921
|
+
**Integration Tests**
|
922
|
+
|
923
|
+
Using integration tests with FactoryGirl may save multiple copies of
|
924
|
+
your test files within the app. To avoid this, specify a custom path in
|
925
|
+
the `config/environments/test.rb` like so:
|
926
|
+
|
927
|
+
```ruby
|
928
|
+
Paperclip::Attachment.default_options[:path] = "#{Rails.root}/spec/test_files/:class/:id_partition/:style.:extension"
|
929
|
+
```
|
930
|
+
|
931
|
+
Then, make sure to delete that directory after the test suite runs by adding
|
932
|
+
this to `spec_helper.rb`.
|
933
|
+
|
934
|
+
```ruby
|
935
|
+
config.after(:suite) do
|
936
|
+
FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"])
|
937
|
+
end
|
938
|
+
```
|
939
|
+
---
|
940
|
+
|
728
941
|
Contributing
|
729
942
|
------------
|
730
943
|
|
@@ -740,19 +953,25 @@ guidelines:
|
|
740
953
|
|
741
954
|
Please see `CONTRIBUTING.md` for more details on contributing and running test.
|
742
955
|
|
743
|
-
|
956
|
+
Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/contributors)!
|
957
|
+
|
958
|
+
License
|
744
959
|
-------
|
745
960
|
|
746
|
-
|
961
|
+
Paperclip is Copyright © 2008-2015 thoughtbot, inc. It is free software, and may be
|
962
|
+
redistributed under the terms specified in the MIT-LICENSE file.
|
747
963
|
|
748
|
-
|
964
|
+
About thoughtbot
|
965
|
+
----------------
|
749
966
|
|
750
|
-
|
967
|
+
![thoughtbot](https://thoughtbot.com/logo.png)
|
751
968
|
|
969
|
+
Paperclip is maintained and funded by thoughtbot.
|
752
970
|
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
753
971
|
|
754
|
-
|
755
|
-
|
972
|
+
We love open source software!
|
973
|
+
See [our other projects][community] or
|
974
|
+
[hire us][hire] to design, develop, and grow your product.
|
756
975
|
|
757
|
-
|
758
|
-
|
976
|
+
[community]: https://thoughtbot.com/community?utm_source=github
|
977
|
+
[hire]: https://thoughtbot.com?utm_source=github
|