This repository has been archived by the owner on Jan 9, 2019. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Pedro Rodrigues
committed
Oct 2, 2012
1 parent
c5b1226
commit e8b3b6f
Showing
12 changed files
with
335 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2010 [Martin Caruso] | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,59 @@ | ||
paperclip_database | ||
================== | ||
|
||
Adds support for storing a paperclip attachment file contents in a database table | ||
Adds support for storing a paperclip attachment file contents in a database table. | ||
|
||
Requirements | ||
------------ | ||
|
||
Paperclip_database requires [Paperclip](https://github.com/thoughtbot/paperclip) version **>= 3.2.0**. | ||
|
||
Installation | ||
------------ | ||
|
||
Paperclip_database is distributed as a gem, and that is how it should be used in your app. | ||
|
||
Include the gem in your `Gemfile`, from rubygems: | ||
|
||
gem 'paperclip_database', '>= 3.2.0' | ||
|
||
Or, get the master branch from the repository: | ||
|
||
gem 'paperclip_database', :git => 'git://github.com/gokuu/paperclip_database.git' | ||
|
||
Usage | ||
----- | ||
|
||
All you need to do is, when defining a [Paperclip](https://github.com/thoughtbot/paperclip) attachment, set its `:storage` option as `:database`: | ||
|
||
```ruby | ||
class MyModel < ActiveRecord::Base | ||
has_attached_file :attachment, | ||
:storage => :database, | ||
:styles => { | ||
:medium => "300x300>", | ||
:thumb => "100x100>" | ||
}, | ||
:url => "/:class/:attachment/:id/:style/:basename.:extension" | ||
end | ||
``` | ||
|
||
Remarks | ||
------- | ||
|
||
The migration defined by `paperclip_database` contains several indexes, as every possible combination of the fields that can identify a single attachment. This should help getting an attachment as quickly as possible using any combination of parameters | ||
|
||
Limitations | ||
----------- | ||
|
||
* Paperclip-database currently only supports one database attachment per model. | ||
* Although you can define a custom :url option for getting the attachment, make sure you define one that uniquelly identifies each attachment, otherwise the plugin will raise an Exception. | ||
|
||
TO-DO | ||
----- | ||
|
||
* Add tests! | ||
* Add support for more than one database attachment per model | ||
* Enable defining a separate table for each different attachment | ||
|
||
Copyright (c) 2012 [Pedro Rodrigues], released under the MIT license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require 'rake' | ||
require 'rake/testtask' | ||
require 'rake/rdoctask' | ||
|
||
desc 'Default: run unit tests.' | ||
task :default => :test | ||
|
||
desc 'Test the paperclip_database gem' | ||
Rake::TestTask.new(:test) do |t| | ||
t.libs << 'lib' | ||
t.libs << 'test' | ||
t.pattern = 'test/**/*_test.rb' | ||
t.verbose = true | ||
end | ||
|
||
desc 'Generate documentation for the paperclip_database gem' | ||
Rake::RDocTask.new(:rdoc) do |rdoc| | ||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = 'Paperclipdb' | ||
rdoc.options << '--line-numbers' << '--inline-source' | ||
rdoc.rdoc_files.include('README') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end |
19 changes: 19 additions & 0 deletions
19
app/controllers/paperclip_database/attachments_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
class PaperclipDatabase::AttachmentsController < ApplicationController | ||
def get_attachment | ||
conditions = {} | ||
conditions[:attached_type] = params[:class] if params[:class] | ||
conditions[:attached_id] = params[:id] if params[:id] | ||
conditions[:attached_id] ||= params[:id_partition].gsub(/\//, '').to_i if params[:id_partition] | ||
conditions[:attachment_name] = params[:attachment] if params[:attachment] | ||
conditions[:style] = params[:style] if params[:style] | ||
|
||
|
||
attachments = PaperclipDatabase::Attachment.where(conditions) | ||
|
||
raise ActionController::RoutingError.new('Image not Found') if attachments.empty? | ||
raise ActionController::RoutingError.new('Too many images found. Check your route definition') if attachments.length > 1 | ||
|
||
attachment = attachments.first | ||
send_data attachment.file_data, :type => attachment.content_type | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module PaperclipDatabase | ||
class Attachment < ActiveRecord::Base | ||
belongs_to :attached, :polymorphic => true | ||
|
||
attr_accessible :style, :file_data, :content_type, :file_size, :attachment_name | ||
|
||
def self.table_name | ||
return 'paperclip_database_attachments' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
Rails.application.routes.draw do | ||
# Dynamically create routes based on defined attachments | ||
Rails.application.eager_load! | ||
|
||
loaded_url_templates = [] | ||
must_create_default_route = false | ||
|
||
Paperclip.classes_with_attachments.each do |class_name| | ||
klass = class_name.constantize | ||
|
||
klass.attachment_definitions.each do |attachment_name, definition| | ||
must_create_default_route = true and next unless definition.has_key?(:url) | ||
next if loaded_url_templates.include?(definition[:url]) | ||
|
||
loaded_url_templates << definition[:url] | ||
|
||
#ap [klass.name, attachment_name, definition] | ||
get definition[:url] => 'paperclip_database/attachments#get_attachment' | ||
end | ||
end | ||
|
||
# Generate the default route, if necessary | ||
if must_create_default_route | ||
get Paperclip::Attachment.default_options[:url] => 'paperclip_database/attachments#get_attachment' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
class CreatePaperclipDatabaseAttachments < ActiveRecord::Migration | ||
def self.up | ||
create_table :paperclip_database_attachments do |t| | ||
t.string :attached_type, :null => false | ||
t.integer :attached_id, :null => false | ||
t.string :attachment_name, :null => false | ||
t.string :style, :null => false | ||
t.binary :file_data, :null => false | ||
t.string :content_type | ||
t.integer :file_size | ||
t.timestamps | ||
end | ||
add_index :paperclip_database_attachments, [ :attached_type, :attached_id, :attachment_name, :style ], :unique => true, :name => :idx_attachments_1 | ||
add_index :paperclip_database_attachments, [ :attached_type, :attached_id, :attachment_name ], :name => :idx_attachments_2 | ||
add_index :paperclip_database_attachments, [ :attached_type, :attached_id ], :name => :idx_attachments_3 | ||
add_index :paperclip_database_attachments, [ :attached_type ], :name => :idx_attachments_4 | ||
add_index :paperclip_database_attachments, [ :attached_type, :attached_id, :style ], :name => :idx_attachments_5 | ||
add_index :paperclip_database_attachments, [ :attached_type, :style ], :name => :idx_attachments_6 | ||
add_index :paperclip_database_attachments, [ :style ], :name => :idx_attachments_7 | ||
add_index :paperclip_database_attachments, [ :attached_type, :attachment_name, :style ], :name => :idx_attachments_8 | ||
add_index :paperclip_database_attachments, [ :attachment_name, :style ], :name => :idx_attachments_9 | ||
add_index :paperclip_database_attachments, [ :attachment_name ], :name => :idx_attachments_10 | ||
add_index :paperclip_database_attachments, [ :attached_type, :attachment_name, :style ], :name => :idx_attachments_11 | ||
add_index :paperclip_database_attachments, [ :attachment_name, :style ], :name => :idx_attachments_12 | ||
add_index :paperclip_database_attachments, [ :style ], :name => :idx_attachments_13 | ||
end | ||
|
||
def self.down | ||
drop_table :paperclip_database_attachments | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#require 'paperclip_database/storage.rb' | ||
require 'paperclip_database' | ||
require 'paperclip_database/storage/database' | ||
require 'rails' | ||
require 'paperclip' | ||
|
||
# This will load the necessary models and controllers | ||
module PaperclipDatabase | ||
class Engine < Rails::Engine | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
module Paperclip | ||
module Storage | ||
module Database | ||
def self.extended(base) | ||
base.instance_eval do | ||
override_default_options base | ||
end | ||
end | ||
|
||
def override_default_options(base) | ||
@path = @url | ||
end | ||
|
||
private :override_default_options | ||
|
||
def exists?(style = default_style) | ||
return !get_attachment(style).nil? | ||
end | ||
|
||
def path(style = default_style) | ||
return style | ||
end | ||
|
||
def get_attachment(style) | ||
return PaperclipDatabase::Attachment.find(:first, :conditions => { | ||
:style => style, | ||
:attached_type => self.instance.class.name, | ||
:attached_id => self.instance.id, | ||
:attachment_name => self.get_attachment_definitions.keys.first | ||
}) | ||
end | ||
|
||
def get_attachment_definitions | ||
attachment_definitions = self.instance.class.attachment_definitions | ||
|
||
if attachment_definitions.select { |k,v| v[:storage] == :database }.count > 1 | ||
raise Exception.new('paperclip-database does not support more than one attachment per model') | ||
end | ||
|
||
return attachment_definitions | ||
end | ||
|
||
|
||
def to_file style = default_style | ||
if @queued_for_write[style] | ||
@queued_for_write[style] | ||
elsif exists?(style) | ||
attachment = get_attachment(style) | ||
tempfile = Tempfile.new attachment.base_name | ||
tempfile.write attachment.file_data | ||
tempfile | ||
else | ||
nil | ||
end | ||
end | ||
|
||
def flush_writes | ||
puts("[paperclip] Writing files #{@queued_for_write.count}") | ||
attachment_definitions = get_attachment_definitions | ||
|
||
@queued_for_write.each do |style, file| | ||
puts("[paperclip] Writing files for #{file} #{style}") | ||
|
||
PaperclipDatabase::Attachment.new do |a| | ||
a.attached_type = self.instance.class.name | ||
a.attached_id = self.instance.id | ||
a.style = style | ||
a.content_type = self.instance_variable_get("@_#{self.name.to_s}_content_type") | ||
a.attachment_name = attachment_definitions.keys.first | ||
a.file_size = file.size | ||
a.file_data = file.read | ||
end.save | ||
end | ||
@queued_for_write = {} | ||
end | ||
|
||
def flush_deletes | ||
@queued_for_delete.each do |style| | ||
puts("[paperclip] Deleting files for #{style}") | ||
attachment = get_attachment(style) | ||
attachment.destroy if !attachment.nil? | ||
end | ||
@queued_for_delete = [] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module PaperclipDatabase | ||
VERSION = "3.0.0" unless defined? PaperclipDatabase::VERSION | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace :'paperclip-database' do | ||
desc 'Copy necessary migrations to the rails project' | ||
task :setup => :environment do | ||
plugin_root = File.dirname(File.dirname(File.dirname(__FILE__))) | ||
|
||
Dir[File.join(plugin_root, 'db', 'migrate', '*.rb')].each do |file| | ||
# First, check if the migration has already been copied | ||
if Dir[File.join('db', 'migrate', "*#{File.basename(file)}*")].any? | ||
puts "Migration #{File.basename(file)} has already been copied, skipping..." | ||
else | ||
dest_file = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{File.basename(file)}" | ||
dest_dir = File.join(Rails.root, 'db', 'migrate') | ||
|
||
puts "Copying #{File.basename(file)} to #{dest_file}" | ||
|
||
FileUtils.mkdir_p dest_dir | ||
FileUtils.cp(file, File.join(dest_dir, dest_file)) | ||
end | ||
end | ||
end | ||
|
||
task :list => :environment do | ||
ap Paperclip.classes_with_attachments | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
$LOAD_PATH.push File.expand_path("../lib", __FILE__) | ||
require 'paperclip_database/version' | ||
|
||
Gem::Specification.new do |s| | ||
s.name = 'paperclip_database' | ||
s.version = PaperclipDatabase::VERSION | ||
|
||
s.authors = ['Pedro Rodrigues'] | ||
s.date = '2012-10-01' | ||
s.summary = 'Database storage support for paperclip file attachment plugin' | ||
s.description = 'Adds support for storing the contents of files attachment via paperclip plugin on the database' | ||
s.email = 'pedro@bbde.org' | ||
s.extra_rdoc_files = [ 'README' ] | ||
s.files = `git ls-files`.split("\n") | ||
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") | ||
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } | ||
s.require_paths = ['lib'] | ||
s.required_ruby_version = ">= 1.9.2" | ||
|
||
s.homepage = 'http://github.com/gokuu/paperclip_database' | ||
|
||
s.add_dependency 'paperclip', [">= 3.0.0"] | ||
end |