acts_as_assets 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +0 -0
- data/Rakefile +28 -0
- data/app/controllers/acts_as_assets/assets_controller.rb +74 -0
- data/app/views/acts_as_assets/assets/destroy.js.erb +1 -0
- data/app/views/acts_as_assets/assets/index.html.erb +12 -0
- data/config/routes.rb +2 -0
- data/lib/acts_as_assets/base.rb +62 -0
- data/lib/acts_as_assets/engine.rb +4 -0
- data/lib/acts_as_assets/interpolations.rb +18 -0
- data/lib/acts_as_assets/version.rb +3 -0
- data/lib/acts_as_assets.rb +3 -0
- data/lib/tasks/acts_as_assets_tasks.rake +4 -0
- data/spec/acts_as_assets_spec.rb +126 -0
- data/spec/controllers/assets_controller_spec.rb +139 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +62 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +3 -0
- data/spec/dummy/log/test.log +8247 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/resources/jpg_test.jpg +0 -0
- data/spec/routing/assets_routing_spec.rb +17 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/support/book.rb +3 -0
- data/spec/support/books_asset.rb +6 -0
- data/spec/support/books_assets_controller.rb +3 -0
- data/spec/support/books_assets_test_doc.rb +6 -0
- metadata +211 -0
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'ActsAsAssets'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class ActsAsAssets::AssetsController < ApplicationController
|
2
|
+
before_filter "assign_root_model"
|
3
|
+
before_filter "assign_target", :only => [:index,:destroy]
|
4
|
+
|
5
|
+
def index
|
6
|
+
load_assets
|
7
|
+
render 'acts_as_assets/assets/index', :layout => false
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
name = root_model_name
|
12
|
+
klazz = ([name.pluralize.camelize] << params[:type]).join('::')
|
13
|
+
@asset = klazz.constantize.create!(:asset => params[:file],
|
14
|
+
"#{name}".to_sym => instance_variable_get("@#{name}".to_sym))
|
15
|
+
|
16
|
+
respond_to do |format|
|
17
|
+
if @asset.valid?
|
18
|
+
format.js { render :json => {:success => true} }
|
19
|
+
else
|
20
|
+
format.js { render :json =>{:success => false, :errors => @asset.errors} }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
|
27
|
+
begin
|
28
|
+
@asset = instance_variable_get("@#{root_model_name}").send(:assets).find_by_id(params[:id])
|
29
|
+
@asset.destroy
|
30
|
+
rescue Exception => e
|
31
|
+
error = e.message
|
32
|
+
end
|
33
|
+
|
34
|
+
respond_to do |format|
|
35
|
+
if error.nil?
|
36
|
+
format.js { render 'acts_as_assets/assets/destroy'}
|
37
|
+
else
|
38
|
+
format.js { render :json => {:success => false, :errors => error} }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def load_assets
|
48
|
+
name = root_model_name
|
49
|
+
klazz = ([name.pluralize.camelize] << params[:type]).join('::')
|
50
|
+
@assets = klazz.constantize.send(:where,"#{name}_id".to_sym => params["#{name}_id".to_sym])
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_root_model
|
54
|
+
name = root_model_name
|
55
|
+
instance_variable_set "@#{name}", name.camelize.constantize.send(:find, params["#{name}_id".to_sym])
|
56
|
+
end
|
57
|
+
|
58
|
+
def root_model_name
|
59
|
+
ActiveSupport::Inflector.underscore(self.class.to_s.split('::').first.singularize)
|
60
|
+
end
|
61
|
+
|
62
|
+
def assign_target
|
63
|
+
@target = params[:target]
|
64
|
+
end
|
65
|
+
|
66
|
+
def destroy_path doc
|
67
|
+
name = root_model_name
|
68
|
+
method = "#{name.pluralize}_assets_destroy_path"
|
69
|
+
send(method.to_sym, instance_variable_get("@#{name}"), :asset_id => doc.id, :target => @target)
|
70
|
+
end
|
71
|
+
helper_method :destroy_path
|
72
|
+
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
K.ajax.loadDiv("<%= @target %>", true);
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%# coding: utf-8 %>
|
2
|
+
<% @assets.each do |doc| %>
|
3
|
+
|
4
|
+
<div class="grid_6 document_link">
|
5
|
+
<%= link_to doc.asset.to_file.original_filename, doc.asset.url %>
|
6
|
+
<%= link_to t('destroy'), destroy_path(doc),
|
7
|
+
:method => :delete, :confirm => 'Sei Sicuro?', :remote => true %>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div class="clear"></div>
|
11
|
+
|
12
|
+
<% end %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module ActsAsAssets
|
2
|
+
|
3
|
+
module Base
|
4
|
+
|
5
|
+
def self.included base
|
6
|
+
base.class_eval do
|
7
|
+
extend ClassMethods
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
def acts_as_assets
|
16
|
+
include InstanceMethods
|
17
|
+
|
18
|
+
belongs_to root_model
|
19
|
+
has_attached_file :asset,
|
20
|
+
:url => "/#{root_model.to_s.pluralize}/:acts_as_assets_root_id/assets/:acts_as_assets_asset_id",
|
21
|
+
:path => ":acts_as_assets_file_path/:acts_as_assets_file_name.:extension"
|
22
|
+
before_create :touch_counter
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def root_model
|
27
|
+
ActiveSupport::Inflector.underscore(self.to_s.split('::').first.singularize).to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
module InstanceMethods
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def touch_counter
|
37
|
+
max = self.class.maximum(:counter, :conditions => {"#{self.class.root_model}_id".to_sym => self.send("#{self.class.root_model}_id".to_sym)})
|
38
|
+
self.counter = max.nil? ? 1 : max+1
|
39
|
+
end
|
40
|
+
|
41
|
+
def root_id
|
42
|
+
send(self.class.root_model).id
|
43
|
+
end
|
44
|
+
|
45
|
+
def acts_as_assets_file_path
|
46
|
+
a = ActiveSupport::Inflector.underscore(self.type).split('/').prepend "public", "system"
|
47
|
+
a.pop
|
48
|
+
root_model_index = a.index(self.class.root_model.to_s.pluralize)
|
49
|
+
a.insert root_model_index + 1,root_id
|
50
|
+
a.join '/'
|
51
|
+
end
|
52
|
+
|
53
|
+
def acts_as_assets_file_name
|
54
|
+
a = ActiveSupport::Inflector.underscore(self.type).split('/')
|
55
|
+
self.counter > 1 ? "#{a.last}_#{counter}" : a.last
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
ActiveRecord::Base.send :include, ActsAsAssets::Base
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'paperclip'
|
2
|
+
|
3
|
+
Paperclip.interpolates :acts_as_assets_root_id do |doc, style|
|
4
|
+
doc.instance.send(:root_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
Paperclip.interpolates :acts_as_assets_file_path do |doc, style|
|
8
|
+
doc.instance.send(:acts_as_assets_file_path)
|
9
|
+
end
|
10
|
+
|
11
|
+
Paperclip.interpolates :acts_as_assets_file_name do |doc, style|
|
12
|
+
doc.instance.send(:acts_as_assets_file_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
Paperclip.interpolates :acts_as_assets_asset_id do |doc, style|
|
16
|
+
doc.instance.id
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "ActsAsAssets" do
|
4
|
+
|
5
|
+
let(:book) { Book.create!(:title => "my new book") }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@docs = []
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
@docs.each { |d| d.destroy }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "model that acts as assets" do
|
16
|
+
subject { Books::Asset.new }
|
17
|
+
it { should belong_to(:book) }
|
18
|
+
it { should have_attached_file(:asset) }
|
19
|
+
it { should have_db_column(:type).of_type(:string) }
|
20
|
+
it { should have_db_column(:counter).of_type(:integer).with_options(:default => 0, :null => false) }
|
21
|
+
it { should have_db_column(:book_id).of_type(:integer) }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "methods" do
|
25
|
+
subject { Books::Assets::TestDoc.new }
|
26
|
+
|
27
|
+
context "given a class of type Books::Assets::TestDoc" do
|
28
|
+
|
29
|
+
describe "root_model" do
|
30
|
+
it "should return :book" do
|
31
|
+
subject.class.root_model.should eq :book
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "acts_as_assets_file_name" do
|
36
|
+
|
37
|
+
it "should return test_doc" do
|
38
|
+
b = book
|
39
|
+
subject.book_id = b.id
|
40
|
+
subject.save!
|
41
|
+
subject.send(:acts_as_assets_file_name).should eq 'test_doc'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should append counter number is is greater than 1" do
|
45
|
+
b = book
|
46
|
+
subject.book_id = b.id
|
47
|
+
subject.save!
|
48
|
+
subject.counter = 4
|
49
|
+
subject.send(:acts_as_assets_file_name).should eq 'test_doc_4'
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "acts_as_assets_file_path" do
|
55
|
+
it "should return public/system/books/assets" do
|
56
|
+
b = book
|
57
|
+
subject.book_id = b.id
|
58
|
+
subject.save!
|
59
|
+
subject.send(:acts_as_assets_file_path).should eq "public/system/books/#{book.id}/assets"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "root_id" do
|
64
|
+
it "should return book.id" do
|
65
|
+
b = book
|
66
|
+
subject.book_id = b.id
|
67
|
+
subject.save!
|
68
|
+
subject.send(:root_id).should eq b.id
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "touch_counter" do
|
73
|
+
|
74
|
+
it "should set counter = 1 by default if counter is actually nil" do
|
75
|
+
subject.send :touch_counter
|
76
|
+
subject.counter.should eq 1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "callbacks" do
|
84
|
+
|
85
|
+
context "before_create" do
|
86
|
+
|
87
|
+
describe "touch_counter" do
|
88
|
+
|
89
|
+
it "should increase counter by one if a document of the same type are created" do
|
90
|
+
dc = Books::Assets::TestDoc.create!
|
91
|
+
@docs << dc
|
92
|
+
dc2 = Books::Assets::TestDoc.create!
|
93
|
+
@docs << dc2
|
94
|
+
Books::Asset.find(dc.id).counter.should eq 1
|
95
|
+
Books::Asset.find(dc2.id).counter.should eq 2
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
context "interpolations" do
|
103
|
+
|
104
|
+
describe "path/url" do
|
105
|
+
|
106
|
+
it "should interpolate the correct path for a subclass instance" do
|
107
|
+
b = book
|
108
|
+
doc = Books::Assets::TestDoc.create! :asset => jpg_test, :book => b
|
109
|
+
@docs << doc
|
110
|
+
doc.asset.path.should eq "public/system/books/#{b.id}/assets/test_doc.jpg"
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should interpolate the correct url for a subclass instance" do
|
114
|
+
b = book
|
115
|
+
doc = Books::Assets::TestDoc.create! :asset => jpg_test, :book => b
|
116
|
+
@docs << doc
|
117
|
+
doc.asset.url.should match /\/books\/#{b.id}\/assets\/#{doc.id}/
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Books::AssetsController do
|
4
|
+
render_views
|
5
|
+
let(:book) { Book.create!(:title => "my new book") }
|
6
|
+
let(:target){'target_div'}
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
@docs = []
|
10
|
+
end
|
11
|
+
|
12
|
+
after :all do
|
13
|
+
@docs.each { |d| d.destroy }
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
context "given a Books::AssetsController controller " do
|
18
|
+
|
19
|
+
describe "root_model_name" do
|
20
|
+
it "should return book" do
|
21
|
+
subject.send(:root_model_name).should eq 'book'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "destroy_path" do
|
26
|
+
before do
|
27
|
+
@book = book
|
28
|
+
@asset = Books::Assets::TestDoc.create!(:book => @book, :asset => jpg_test)
|
29
|
+
@docs << @asset
|
30
|
+
get :index, :book_id => @book.id, :type => ["Assets","TestDoc"]
|
31
|
+
end
|
32
|
+
it "should return /books/id/assets/asset_id" do
|
33
|
+
subject.send(:destroy_path,@asset).should eq "/books/#{@book.id}/assets/#{@asset.id}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
context "filters" do
|
40
|
+
|
41
|
+
context "assign_root_model" do
|
42
|
+
|
43
|
+
before do
|
44
|
+
@book = book
|
45
|
+
get :index, :book_id => @book.id, :type => ["Assets","TestDoc"]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should assign @book" do
|
49
|
+
subject.assign_to(:book)
|
50
|
+
assigns(:book).id.should eq @book.id
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "index" do
|
57
|
+
|
58
|
+
before :each do
|
59
|
+
@book = book
|
60
|
+
@asset = Books::Assets::TestDoc.create!(:book => @book, :asset => jpg_test)
|
61
|
+
@docs << @asset
|
62
|
+
get :index, :book_id => book.id, :type => ["Assets","TestDoc"], :target => target, :format => :js
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should assign variables" do
|
66
|
+
should assign_to(:assets)
|
67
|
+
should assign_to(:target)
|
68
|
+
should assign_to(:book)
|
69
|
+
end
|
70
|
+
|
71
|
+
it{should respond_with(:success)}
|
72
|
+
|
73
|
+
it{should render_template('acts_as_assets/assets/index')}
|
74
|
+
|
75
|
+
it "should return the correct formatted view" do
|
76
|
+
response.body.should match(/#{@asset.asset.to_file.original_filename}/)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "create" do
|
82
|
+
|
83
|
+
before do
|
84
|
+
@book = book
|
85
|
+
post :create, :book_id => @book.id, :type => ["Assets","TestDoc"], :file => jpg_test, :format => "js"
|
86
|
+
@docs << assigns(:asset)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should assign variables" do
|
90
|
+
should assign_to(:asset)
|
91
|
+
should assign_to(:book)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should be success returning the correct content type" do
|
95
|
+
should respond_with_content_type(:js)
|
96
|
+
should respond_with(:success)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should correctly save the file" do
|
100
|
+
File.exist?(File.expand_path(assigns(:asset).asset.path)).should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "destroy" do
|
106
|
+
|
107
|
+
before :each do
|
108
|
+
@book = book
|
109
|
+
@asset = Books::Assets::TestDoc.create!(:book => @book, :asset => jpg_test)
|
110
|
+
delete :destroy, :book_id => @book.id, :id => @asset.id, :format => "js", :target => target
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should assign variables" do
|
114
|
+
should assign_to(:asset)
|
115
|
+
should assign_to(:target)
|
116
|
+
should assign_to(:book)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should be success returning the correct content type" do
|
120
|
+
should respond_with_content_type(:js)
|
121
|
+
should respond_with(:success)
|
122
|
+
end
|
123
|
+
|
124
|
+
it{should render_template('acts_as_assets/assets/destroy')}
|
125
|
+
|
126
|
+
it "should return the correct js to execute" do
|
127
|
+
response.body.should match(/#{target}/)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should correctly delete the file" do
|
131
|
+
File.exist?(File.expand_path(@asset.asset.path)).should be_false
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
end
|