nifty-attachments 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/nifty/attachments.rb +4 -0
- data/lib/nifty/attachments/attachment.rb +53 -0
- data/lib/nifty/attachments/middleware.rb +29 -0
- data/lib/nifty/attachments/migration.rb +16 -0
- data/lib/nifty/attachments/migration_generator.rb +21 -0
- data/lib/nifty/attachments/model_extension.rb +47 -0
- data/lib/nifty/attachments/railtie.rb +24 -0
- data/lib/nifty/attachments/version.rb +5 -0
- metadata +53 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
class Attachment < ActiveRecord::Base
|
4
|
+
|
5
|
+
# Set the table name
|
6
|
+
self.table_name = 'nifty_attachments'
|
7
|
+
|
8
|
+
# This will be the ActionDispatch::UploadedFile object which be diseminated
|
9
|
+
# by the class on save.
|
10
|
+
attr_accessor :uploaded_file
|
11
|
+
|
12
|
+
# Relationships
|
13
|
+
belongs_to :parent, :polymorphic => true
|
14
|
+
|
15
|
+
# Validations
|
16
|
+
validates :file_name, :presence => true
|
17
|
+
validates :file_type, :presence => true
|
18
|
+
validates :data, :presence => true
|
19
|
+
validates :digest, :presence => true
|
20
|
+
validates :token, :presence => true, :uniqueness => true
|
21
|
+
|
22
|
+
# All attachments should have a token assigned to this
|
23
|
+
before_validation { self.token = SecureRandom.uuid if self.token.blank? }
|
24
|
+
|
25
|
+
# Copy values from the `uploaded_file` and set them as the appropriate
|
26
|
+
# fields on this model
|
27
|
+
before_validation do
|
28
|
+
if self.uploaded_file
|
29
|
+
self.data = self.uploaded_file.tempfile.read
|
30
|
+
self.file_name = self.uploaded_file.original_filename
|
31
|
+
self.file_type = self.uploaded_file.content_type
|
32
|
+
self.digest = Digest::MD5.hexdigest(self.data)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return the attachment for a given role
|
37
|
+
def self.for(role)
|
38
|
+
self.where(:role => role).first
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return the path to the attachment
|
42
|
+
def path
|
43
|
+
"/attachment/#{token}/#{file_name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Is the attachment an image?
|
47
|
+
def image?
|
48
|
+
file_type =~ /\Aimage\//
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
class Middleware
|
4
|
+
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
if env['PATH_INFO'] =~ /\A\/attachment\/([a-f0-9\-]{36})\/(.*)/
|
11
|
+
if attachment = Nifty::Attachments::Attachment.find_by_token($1)
|
12
|
+
[200, {
|
13
|
+
'Content-Length' => attachment.data.bytesize.to_s,
|
14
|
+
'Content-Type' => attachment.file_type,
|
15
|
+
'Cache-Control' => "public, maxage=#{1.year.to_i}",
|
16
|
+
'Content-Disposition' => "attachment; filename=\"#{attachment.file_name}\""
|
17
|
+
},
|
18
|
+
[attachment.data]]
|
19
|
+
else
|
20
|
+
[404, {}, ["Attachment not found"]]
|
21
|
+
end
|
22
|
+
else
|
23
|
+
@app.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateNiftyAttachmentsTable < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def up
|
4
|
+
create_table :nifty_attachments do |t|
|
5
|
+
t.integer :parent_id
|
6
|
+
t.string :parent_type, :token, :digest, :role, :file_name, :file_type
|
7
|
+
t.binary :data, :limit => 10.megabytes
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def down
|
13
|
+
drop_table :nifty_attachments
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module Nifty
|
5
|
+
module Attachments
|
6
|
+
class MigrationGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
|
9
|
+
source_root File.expand_path("../", __FILE__)
|
10
|
+
|
11
|
+
def self.next_migration_number(path)
|
12
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_model_file
|
16
|
+
migration_template 'migration.rb', "db/migrate/create_nifty_attachments_table"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
module ModelExtension
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
base.before_save do
|
8
|
+
if @pending_attachments
|
9
|
+
@pending_attachments.each do |pa|
|
10
|
+
old_attachments = self.nifty_attachments.where(:role => pa[:role]).pluck(:id)
|
11
|
+
self.nifty_attachments.create(:uploaded_file => pa[:file], :role => pa[:role])
|
12
|
+
self.nifty_attachments.where(:id => old_attachments).destroy_all
|
13
|
+
end
|
14
|
+
@pending_attachments = nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def attachment(name)
|
22
|
+
unless self.reflect_on_all_associations(:has_many).map(&:name).include?(:nifty_attachments)
|
23
|
+
has_many :nifty_attachments, :as => :parent, :dependent => :destroy, :class_name => 'Nifty::Attachments::Attachment'
|
24
|
+
end
|
25
|
+
|
26
|
+
has_one name, -> { select(:id, :token, :digest, :parent_id, :parent_type, :file_name, :file_type).where(:role => name) }, :class_name => 'Nifty::Attachments::Attachment', :as => :parent
|
27
|
+
|
28
|
+
define_method "#{name}_file" do
|
29
|
+
instance_variable_get("@#{name}_file")
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method "#{name}_file=" do |file|
|
33
|
+
instance_variable_set("@#{name}_file", file)
|
34
|
+
if file.is_a?(ActionDispatch::Http::UploadedFile)
|
35
|
+
@pending_attachments ||= []
|
36
|
+
@pending_attachments << {:role => name, :file => file}
|
37
|
+
else
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
class Railtie < Rails::Railtie #:nodoc:
|
4
|
+
|
5
|
+
initializer 'nifty.attachments.initialize' do |app|
|
6
|
+
|
7
|
+
require 'nifty/attachments/middleware'
|
8
|
+
app.config.middleware.use Nifty::Attachments::Middleware
|
9
|
+
|
10
|
+
ActiveSupport.on_load(:active_record) do
|
11
|
+
require 'nifty/attachments/attachment'
|
12
|
+
require 'nifty/attachments/model_extension'
|
13
|
+
::ActiveRecord::Base.send :include, Nifty::Attachments::ModelExtension
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
generators do
|
19
|
+
require 'nifty/attachments/migration_generator'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nifty-attachments
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Cooke
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-07 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Attach documents & files to Active Record models
|
15
|
+
email:
|
16
|
+
- adam@niftyware.io
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/nifty/attachments/attachment.rb
|
22
|
+
- lib/nifty/attachments/middleware.rb
|
23
|
+
- lib/nifty/attachments/migration.rb
|
24
|
+
- lib/nifty/attachments/migration_generator.rb
|
25
|
+
- lib/nifty/attachments/model_extension.rb
|
26
|
+
- lib/nifty/attachments/railtie.rb
|
27
|
+
- lib/nifty/attachments/version.rb
|
28
|
+
- lib/nifty/attachments.rb
|
29
|
+
homepage: https://github.com/niftyware/attachments
|
30
|
+
licenses: []
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.23
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: Attach documents & files to Active Record models
|
53
|
+
test_files: []
|