lib/paperclip/storage/database.rb in paperclip_database-2.2.2 vs lib/paperclip/storage/database.rb in paperclip_database-2.3.0
- old
+ new
@@ -56,11 +56,13 @@
#
module Database
def self.extended(base)
base.instance_eval do
- setup_paperclip_files_model
+ setup_attachment_class
+ setup_paperclip_file_model
+ setup_paperclip_files_association
override_default_options base
end
Paperclip.interpolates(:database_path) do |attachment, style|
attachment.database_path(style)
end
@@ -77,34 +79,46 @@
end
ActiveRecord::Base.logger.info("[paperclip] Database Storage Initalized.")
end
- def setup_paperclip_files_model
- # If the model is in a namespace, look up that module
- if instance.class.name.include?('::')
- module_name = PaperclipDatabase::deconstantize(instance.class.name)
- @paperclip_class_module = module_name.constantize rescue Object
+ def setup_paperclip_files_association
+ @paperclip_files_association_name = 'paperclip_files'
+ @database_table = @paperclip_file_model.table_name
+ #FIXME: This fails when using set_table_name "<myname>" in your model
+ #FIXME: This should be fixed in ActiveRecord...
+ instance.class.has_many(@paperclip_files_association_name.to_sym,
+ :class_name => @paperclip_file_model.name,
+ :foreign_key => instance.class.table_name.classify.underscore + '_id'
+ )
+ end
+ private :setup_paperclip_files_association
+
+ def setup_paperclip_file_model
+ class_name = "#{instance.class.table_name.singularize}_#{name.to_s}_paperclip_file".classify
+ if @attachment_class.const_defined?(class_name, false)
+ @paperclip_file_model = @attachment_class.const_get(class_name, false)
else
- @paperclip_class_module = Object
+ @paperclip_file_model = @attachment_class.const_set(class_name, Class.new(::ActiveRecord::Base))
+ @paperclip_file_model.table_name = @options[:database_table] || name.to_s.pluralize
+ @paperclip_file_model.validates_uniqueness_of :style, :scope => instance.class.table_name.classify.underscore + '_id'
+ @paperclip_file_model.scope :file_for, lambda {|style| @paperclip_file_model.where('style = ?', style) }
end
+ end
+ private :setup_paperclip_file_model
- @paperclip_files = "#{instance.class.name.demodulize.underscore}_#{name.to_s}_paperclip_files"
- if !@paperclip_class_module.const_defined?(@paperclip_files.classify)
- @paperclip_file = @paperclip_class_module.const_set(@paperclip_files.classify, Class.new(::ActiveRecord::Base))
- @paperclip_file.table_name = @options[:database_table] || name.to_s.pluralize
- @paperclip_file.validates_uniqueness_of :style, :scope => instance.class.table_name.classify.underscore + '_id'
- @paperclip_file.scope :file_for, lambda {|style| @paperclip_file.where('style = ?', style) }
- else
- @paperclip_file = @paperclip_class_module.const_get(@paperclip_files.classify)
+ def setup_attachment_class
+ instance.class.ancestors.each do |ancestor|
+ # Pick the top-most definition like
+ # Paperclip::AttachmentRegistry#definitions_for
+ names_for_ancestor = ancestor.attachment_definitions.keys rescue []
+ if names_for_ancestor.member?(name)
+ @attachment_class = ancestor
+ end
end
- @database_table = @paperclip_file.table_name
- #FIXME: This fails when using set_table_name "<myname>" in your model
- #FIXME: This should be fixed in ActiveRecord...
- instance.class.has_many @paperclip_files.to_sym, :class_name => @paperclip_file.name, :foreign_key => instance.class.table_name.classify.underscore + '_id'
end
- private :setup_paperclip_files_model
+ private :setup_attachment_class
def copy_to_local_file(style, dest_path)
File.open(dest_path, 'wb+'){|df| to_file(style).tap{|sf| File.copy_stream(sf, df); sf.close;sf.unlink} }
end
@@ -129,11 +143,11 @@
end
end
def exists?(style = default_style)
if original_filename
- instance.send("#{@paperclip_files}").where(:style => style).exists?
+ instance.send("#{@paperclip_files_association_name}").where(:style => style).exists?
else
false
end
end
@@ -155,11 +169,11 @@
end
alias_method :to_io, :to_file
def file_for(style)
- db_result = instance.send("#{@paperclip_files}").send(:file_for, style.to_s)
+ db_result = instance.send("#{@paperclip_files_association_name}").send(:file_for, style.to_s)
raise RuntimeError, "More than one result for #{style}" if db_result.size > 1
db_result.first
end
def file_contents(style = default_style)
@@ -167,17 +181,17 @@
end
def flush_writes
ActiveRecord::Base.logger.info("[paperclip] Writing files for #{name}")
@queued_for_write.each do |style, file|
- case Rails::VERSION::STRING
- when /^3/
- paperclip_file = instance.send(@paperclip_files).send(:find_or_create_by_style, style.to_s)
- when /^4/
- paperclip_file = instance.send(@paperclip_files).send(:find_or_create_by, style: style.to_s)
+ case ActiveModel::VERSION::MAJOR
+ when 3
+ paperclip_file = instance.send(@paperclip_files_association_name).send(:find_or_create_by_style, style.to_s)
+ when 4
+ paperclip_file = instance.send(@paperclip_files_association_name).send(:find_or_create_by, style: style.to_s)
else
- raise "Rails version #{Rails::VERSION::STRING} is not supported (yet)"
+ raise "ActiveModel version #{ActiveModel::VERSION::STRING} is not supported (yet)"
end
paperclip_file.file_contents = file.read
paperclip_file.save!
instance.reload
end
@@ -188,13 +202,13 @@
ActiveRecord::Base.logger.info("[paperclip] Deleting files for #{name}")
@queued_for_delete.uniq! ##This is apparently necessary for paperclip v 3.x
@queued_for_delete.each do |path|
/id=([0-9]+)/.match(path)
if @options[:cascade_deletion] && !instance.class.exists?(instance.id)
- raise RuntimeError, "Deletion has not been done by through cascading." if @paperclip_file.exists?($1)
+ raise RuntimeError, "Deletion has not been done by through cascading." if @paperclip_file_model.exists?($1)
else
- @paperclip_file.destroy $1
+ @paperclip_file_model.destroy $1
end
end
@queued_for_delete = []
end
@@ -202,10 +216,11 @@
def self.included(base)
base.extend(self)
end
def downloads_files_for(model, attachment, options = {})
define_method("#{attachment.to_s.pluralize}") do
- model_record = Object.const_get(model.to_s.camelize.to_sym).find(params[:id])
+ #FIXME: Handling Namespaces
+ model_record = Object.const_get(model.to_s.camelize.to_sym, false).find(params[:id])
style = params[:style] ? params[:style] : 'original'
send_data model_record.send(attachment).file_contents(style),
:filename => model_record.send("#{attachment}_file_name".to_sym),
:type => model_record.send("#{attachment}_content_type".to_sym)
end