diff --git a/README.md b/README.md index 889ee93..ee57504 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ My::Application.routes.draw do end ``` -And you'll have a `/media/*path` route that just delivers whatever Carrierwave uploads to this app, as long as +And you'll have a `/media/:id` route that just delivers whatever Carrierwave uploads to this app, as long as you're using [carrierwave-mongoid](https://github.com/jnicklas/carrierwave-mongoid) to do the uploads. CarrierWave's `grid_fs_access_url` will be set correctly for you, too. @@ -17,7 +17,7 @@ You can specify if any of the paths should respond with `Content-Disposition: at ``` ruby # config/initializers/carrierwave_mongoid_media.rb -CarrierwaveMongoidMedia.force_downloads_on do |path| +CarrierwaveMongoidMedium.force_downloads_on do |path| # return true if the file should get Content-Disposition: attachment end ``` diff --git a/app/concerns/carrierwave_mongoid_media_controller.rb b/app/concerns/carrierwave_mongoid_media_controller.rb new file mode 100644 index 0000000..f4c1e1a --- /dev/null +++ b/app/concerns/carrierwave_mongoid_media_controller.rb @@ -0,0 +1,29 @@ +module CarrierwaveMongoidMediaController + def show + resource.as_response_for(self) + end + + def create + with_ok { create! } + end + + def create! + resource.update_attributes(params) + end + + def destroy + with_ok { destroy! } + end + + def destroy! + resource.destroy + end + + private + def with_ok + yield + + head :ok + end +end + diff --git a/app/controllers/carrierwave/mongoid_media_controller.rb b/app/controllers/carrierwave/mongoid_media_controller.rb new file mode 100644 index 0000000..ea51a6e --- /dev/null +++ b/app/controllers/carrierwave/mongoid_media_controller.rb @@ -0,0 +1,9 @@ +class Carrierwave::MongoidMediaController < ApplicationController + include CarrierwaveMongoidMediaController + + private + def resource + @carrierwave_mongoid_media ||= CarrierwaveMongoidMedium.find(params[:id]) + end +end + diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb deleted file mode 100644 index c46bb70..0000000 --- a/app/controllers/media_controller.rb +++ /dev/null @@ -1,4 +0,0 @@ -class MediaController < ApplicationController - include CarrierWave::Mongoid::Media::ControllerBehavior -end - diff --git a/app/models/carrierwave_mongoid_media.rb b/app/models/carrierwave_mongoid_media.rb deleted file mode 100644 index a863c9e..0000000 --- a/app/models/carrierwave_mongoid_media.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'delegate' - -class CarrierwaveMongoidMedia < SimpleDelegator - def self.find(path) - obj = Mongoid::GridFS[path] - - raise Mongoid::Errors::DocumentNotFound.new(Mongoid::GridFS, :path => path) if !obj - - new(obj) - end - - def self.force_downloads_on(&block) - if block - @block = block - else - @block - end - end - - def attachment_filename - File.basename(self.filename) - end - - def initialize(gridfs_object) - @gridfs_object = gridfs_object - end - - def __getobj__ - @gridfs_object - end - - def force_download? - if block = self.class.force_downloads_on - block.call(self.filename) - else - false - end - end -end - diff --git a/app/models/carrierwave_mongoid_medium.rb b/app/models/carrierwave_mongoid_medium.rb new file mode 100644 index 0000000..8a2b05e --- /dev/null +++ b/app/models/carrierwave_mongoid_medium.rb @@ -0,0 +1,86 @@ +require 'virtus' + +class CarrierwaveMongoidMedium + include Virtus + + attribute :id + attribute :data + + def self.find(id) + medium = new(:id => id) + + raise_not_found(id) if !medium.gridfs_object + + medium + end + + def self.raise_not_found(id) + raise Mongoid::Errors::DocumentNotFound.new(Mongoid::GridFS, :filename => id) + end + + def raise_not_found + self.class.raise_not_found(id) + end + + def self.force_downloads_on(&block) + if block + @block = block + else + @block + end + end + + def update_attributes(new_attributes = {}) + self.attributes = new_attributes + + save + end + + def content_type + gridfs_object.content_type + end + + def self.create(attributes = {}) + new(attributes).save + end + + def destroy + gridfs_object.destroy + + @gridfs_object = nil + end + + def save + attrs = attributes.dup + + file = attrs.delete(:data) + filename = attrs.delete(:id) || attrs.delete(:filename) + + @gridfs_object = Mongoid::GridFS.put(file, attrs.merge(:filename => filename)) + end + + def attachment_filename + ::File.basename(id) + end + + def gridfs_object + @gridfs_object ||= Mongoid::GridFS[id] + end + + def force_download? + if block = self.class.force_downloads_on + block.call self + else + false + end + end + + def as_response_for(controller_instance) + controller_instance.content_type = self.content_type + controller_instance.response_body = self.gridfs_object + if self.force_download? + controller_instance.response.headers['Content-Disposition'] = "attachment; filename='#{self.attachment_filename}'" + end + end +end + diff --git a/carrierwave-mongoid-media.gemspec b/carrierwave-mongoid-media.gemspec index 199dbef..68786ee 100644 --- a/carrierwave-mongoid-media.gemspec +++ b/carrierwave-mongoid-media.gemspec @@ -19,4 +19,5 @@ Gem::Specification.new do |gem| gem.add_dependency 'carrierwave' gem.add_dependency 'carrierwave-mongoid' + gem.add_dependency 'virtus' end diff --git a/lib/carrierwave-mongoid-media.rb b/lib/carrierwave-mongoid-media.rb index 664c4d0..20570aa 100644 --- a/lib/carrierwave-mongoid-media.rb +++ b/lib/carrierwave-mongoid-media.rb @@ -2,5 +2,4 @@ require "carrierwave-mongoid-media/version" if defined?(Rails::Engine) require 'carrierwave-mongoid-media/engine' - require 'carrierwave/mongoid/media/controller_behavior' end diff --git a/lib/carrierwave-mongoid-media/engine.rb b/lib/carrierwave-mongoid-media/engine.rb index 17df0fe..52654c1 100644 --- a/lib/carrierwave-mongoid-media/engine.rb +++ b/lib/carrierwave-mongoid-media/engine.rb @@ -5,6 +5,8 @@ module CarrierWave class Media < ::Rails::Engine DEFAULT_PREFIX = :media + config.autoload_paths << File.expand_path("../../../app/behaviors", __FILE__) + class << self attr_writer :prefix end @@ -16,7 +18,7 @@ module CarrierWave def self.routes(router, options = {}) options = { :prefix => :media, - :controller => :media + :controller => "carrierwave/mongoid_media" }.merge(options) self.prefix = options[:prefix] @@ -26,7 +28,7 @@ module CarrierWave end router.instance_exec do - get "#{options[:prefix]}/*path" => "#{options[:controller]}#show", :as => :media + get "#{options[:prefix]}/:id" => "#{options[:controller]}#show", :as => :media, :id => /.*/ end end end diff --git a/lib/carrierwave/mongoid/media/controller_behavior.rb b/lib/carrierwave/mongoid/media/controller_behavior.rb deleted file mode 100644 index 50597c9..0000000 --- a/lib/carrierwave/mongoid/media/controller_behavior.rb +++ /dev/null @@ -1,17 +0,0 @@ -module CarrierWave::Mongoid::Media::ControllerBehavior - def show - obj = CarrierwaveMongoidMedia.find(path) - - self.content_type = obj.content_type - self.response_body = obj - if obj.force_download? - response.headers['Content-Disposition'] = "attachment; filename='#{obj.attachment_filename}'" - end - end - - private - def path - @path ||= params[:path] + '.' + params[:format] - end -end -