carrierwave-neo4j 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5507ccab191bfca681514fde9d25ad62c56ff8ab
4
- data.tar.gz: b849d9e4f6b4b73c7e985454f6f09fc10235e9b5
2
+ SHA256:
3
+ metadata.gz: ee1ece089b8cbd55532f4c0cba7a7a19054b24edc86f81a077c5497c49f4c801
4
+ data.tar.gz: a8a1b8fb5355129bfb9fd41839b59bbeee38e5808d59cac0a21fcc7ee6291a55
5
5
  SHA512:
6
- metadata.gz: 0911192167258d8be9d4ecf37857dc056725627706c30b2d853c0b6d4e10b8c38cd9fe3d0d90e0b143cc2ef5a8656fe1f0220d1ccac7aa9eeaa0ece0a39cd3ac
7
- data.tar.gz: 4fd214ca10c2f7a0950156760d3bf7a25b45dc2b618026a27118184dc47a9603632e1ef577f4c78dccfc57256178ae103ee0137d3f16f1471cd1fad391b7878e
6
+ metadata.gz: f2adb7d1d88b7f225d2d89c4bdcae75ada1f4fa3edfc5679cbd0aa034c80d6738bc2990dc9a2527555ae92837edbf9f447fb0ed811c9da133d2613c88019dd45
7
+ data.tar.gz: e9168769c2f8e656c3e8e1046e5c7d5fbaaec1d53269525557fe50b3f4a77ba08aa0966529cd5835750b4fe57b7b7a85b5e58aea3ac145b151f93e6c451b9a97
data/.gitignore CHANGED
@@ -6,3 +6,6 @@ db/*
6
6
  .idea
7
7
 
8
8
  .ruby-version
9
+ spec/public/uploads/*
10
+ bin/
11
+
@@ -0,0 +1,35 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [3.0.0] - 2020-07-15
8
+
9
+ ### Fixed
10
+
11
+ - Updated and fixed all tests to work with neo4j.rb 9.x and CarrierWave 2.x
12
+ - Updated the overall format of the plugin to mirror CarrierWave::Orm::ActiveRecord as much as possible
13
+ - Files are now deleted correctly on `#destroy`
14
+ - File information is now correctly reloaded on `#find`
15
+ - Thanks @deobald for all the fixes.
16
+
17
+ ## [2.0.4] - 2018-04-03
18
+
19
+ ### Fixed
20
+
21
+ - Fix the fix from 2.0.3 (`@_mounters` is sometimes `nil`) (thanks @janbiedermann / see #15)
22
+
23
+ ## [2.0.3] - 2018-04-01
24
+
25
+ ### Fixed
26
+
27
+ - Make it work with recent Neo4j (thanks @janbiedermann / see #14)
28
+
29
+ ## [2.0.2]
30
+
31
+ ### Fixed
32
+ - Fixed `gemspec` to allow newer version of `carrierwave` gem (thanks @edenvicary, see #12)
33
+ - Fixed `uninitialized constant CarrierWave::Mount::Mounter` (thanks @thanksoni7uka, see #11 and #12)
34
+
35
+ <!-- CHANGELOG started after version 2.0.1 -->
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in carrierwave_neo4j.gemspec
4
4
  gemspec
5
-
6
- gem 'database_cleaner', github: 'dpisarewski/database_cleaner', branch: 'neo4j'
data/README.md CHANGED
@@ -1,21 +1,81 @@
1
1
  ## CarrierWave for Neo4j
2
2
 
3
- This gem adds support for Neo4j 3.0+ to CarrierWave, see the CarrierWave documentation for more detailed usage instructions.
3
+ This gem adds support for Neo4j 3.0+ (neo4j.rb 9.6.0+) to CarrierWave 2.1.0+, see the CarrierWave documentation for more detailed usage instructions.
4
4
 
5
5
  ### Installation Instructions
6
6
 
7
7
  Add to your Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'carrierwave-neo4j', require: 'carrierwave/neo4j', github: 'dpisarewski/carrierwave-neo4j'
10
+ gem 'carrierwave-neo4j', '~> 3.0', require: 'carrierwave/neo4j'
11
11
  ```
12
- Use it like this:
12
+
13
+ You can see example usage in `spec/neo4j_realistic_spec.rb` but in brief, you can use it like this:
13
14
 
14
15
  ```ruby
16
+ class AttachmentUploader < CarrierWave::Uploader::Base
17
+ storage :file
18
+
19
+ def store_dir
20
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
21
+ end
22
+ end
23
+
15
24
  class Asset
16
25
  include Neo4j::ActiveNode
17
26
 
18
27
  property :attachment, type: String
19
28
  mount_uploader :attachment, AttachmentUploader
20
29
  end
21
- ```
30
+ ```
31
+
32
+ If you want image manipulation, you will need to install ImageMagick
33
+
34
+ On Ubuntu:
35
+
36
+ ```sh
37
+ sudo apt-get install imagemagick --fix-missing
38
+ ```
39
+
40
+ On macOS:
41
+
42
+ ```sh
43
+ brew install imagemagick
44
+ ```
45
+
46
+ ### Development
47
+
48
+ ```sh
49
+ bundle install
50
+ rake neo4j:install[community-latest,test]
51
+ rake neo4j:start[test]
52
+ rake spec
53
+ ```
54
+
55
+ ### Troubleshooting
56
+
57
+ #### Files are nil
58
+
59
+ If you aren't getting your files back after querying a record from Neo4j, be aware that this will only happen automatically for the `Model#find` method. For all other finders (`#all`, `#first`, `#find_by`, `#find_by_*`, `#find_by_*!`, `#last`) you will need to force a reload so the model sees the file. For example:
60
+
61
+ ```ruby
62
+ users = User.all
63
+ users.each(&:reload_from_database!)
64
+ ```
65
+
66
+ Sorry, this sucks. But this is a limitation of Neo4j.rb as these other finders don't fire any callbacks.
67
+
68
+ #### binstubs (particularly `bin/rspec`) seem broken
69
+
70
+ If you're getting some infinite recursion when you run the specs that ultimately results in an error like:
71
+
72
+ ```
73
+ `ensure in require': CRITICAL: RUBYGEMS_ACTIVATION_MONITOR.owned?: before false -> after true (RuntimeError)
74
+ ```
75
+
76
+ You may want to try:
77
+
78
+ ```sh
79
+ rm .bundle/config
80
+ bundle install
81
+ ```
data/Rakefile CHANGED
@@ -1 +1,12 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'neo4j/rake_tasks'
3
+
4
+ begin
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :default => :spec
10
+ rescue LoadError
11
+ puts "RSpec not installed...?"
12
+ end
@@ -7,19 +7,21 @@ Gem::Specification.new do |s|
7
7
  s.version = CarrierWave::Neo4j::VERSION
8
8
  s.authors = ["Rodrigo Navarro"]
9
9
  s.email = ["navarro@manapot.com.br"]
10
- s.homepage = "https://github.com/reu/carrierwave-neo4j"
10
+ s.homepage = "https://github.com/neo4jrb/carrierwave-neo4j"
11
11
  s.summary = %q{Neo4j support for Carrierwave}
12
12
  s.description = %q{Neo4j support for Carrierwave}
13
13
 
14
- s.rubyforge_project = "carrierwave_neo4j"
15
-
16
14
  s.files = `git ls-files`.split("\n")
17
15
  s.test_files = `git ls-files -- {spec}/*`.split("\n")
18
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
17
  s.require_paths = ["lib"]
20
18
 
21
- s.add_dependency("activesupport", ">= 3.0" )
22
- s.add_dependency("neo4j", ">= 1.1")
23
- s.add_dependency("carrierwave", "~> 0.5")
24
- s.add_development_dependency("rspec", "~> 2.0")
19
+ s.add_dependency("activesupport", ">= 6.0" )
20
+ s.add_dependency("neo4j", "~> 9.6.0")
21
+ s.add_dependency("carrierwave", ">= 2.1")
22
+ s.add_development_dependency("rspec", "~> 3.0")
23
+ s.add_development_dependency("rspec-its")
24
+ s.add_development_dependency("webmock")
25
+ s.add_development_dependency("neo4j-rake_tasks")
26
+ s.add_development_dependency("rake")
25
27
  end
@@ -5,71 +5,207 @@ require "carrierwave/validations/active_model"
5
5
  require "carrierwave/neo4j/uploader_converter"
6
6
  require "active_support/concern"
7
7
 
8
+ ######
9
+ # This file attempts to maintain symmetry with:
10
+ # https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/orm/activerecord.rb
11
+ #
12
+ # Behaviours linked to callbacks (ex. `after_save :"store_#{column}!"`) belong to:
13
+ # https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/mount.rb
14
+ # ...which is mixed into Model classes.
15
+ ######
8
16
  module CarrierWave
9
17
  module Neo4j
10
- extend ActiveSupport::Concern
11
18
 
19
+ # this class methods junk is necessary because ActiveNode is implemented as
20
+ # a model instead of a class for god-knows-what-reason.
21
+ extend ActiveSupport::Concern
12
22
  module ClassMethods
23
+
13
24
  include CarrierWave::Mount
25
+
14
26
  ##
15
27
  # See +CarrierWave::Mount#mount_uploader+ for documentation
16
28
  #
17
- def mount_uploader(column, uploader = nil, options = {}, &block)
29
+ def mount_uploader(column, uploader=nil, options={}, &block)
18
30
  super
19
31
 
32
+ mod = Module.new
33
+ prepend mod
34
+ mod.class_eval <<-RUBY, __FILE__, __LINE__+1
35
+ def remote_#{column}_url=(url)
36
+ column = _mounter(:#{column}).serialization_column
37
+ __send__(:"\#{column}_will_change!")
38
+ super
39
+ end
40
+ RUBY
41
+ end
42
+
43
+ ##
44
+ # See +CarrierWave::Mount#mount_uploaders+ for documentation
45
+ #
46
+ def mount_uploaders(column, uploader=nil, options={}, &block)
47
+ super
48
+
49
+ mod = Module.new
50
+ prepend mod
51
+ mod.class_eval <<-RUBY, __FILE__, __LINE__+1
52
+ def remote_#{column}_urls=(url)
53
+ column = _mounter(:#{column}).serialization_column
54
+ __send__(:"\#{column}_will_change!")
55
+ super
56
+ end
57
+ RUBY
58
+ end
59
+
60
+ def add_reload_callback(method)
61
+ @_reload_callbacks = [] unless @_reload_callbacks
62
+ @_reload_callbacks << method unless @_reload_callbacks.include?(method)
63
+ end
64
+
65
+ def reload_callbacks
66
+ @_reload_callbacks
67
+ end
68
+
69
+ private
70
+
71
+ def mount_base(column, uploader=nil, options={}, &block)
72
+ super
73
+
74
+ # this seems necessary to prevent the _identifier from including
75
+ # the entire path ('img.jpg' vs. '/uploads/user/image/img.jpg')
20
76
  serialize column, ::CarrierWave::Uploader::Base
21
77
 
22
78
  include CarrierWave::Validations::ActiveModel
23
79
 
24
- validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
80
+ validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
25
81
  validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
82
+ validates_download_of column if uploader_option(column.to_sym, :validate_download)
83
+
84
+ # carrierwave keeps a instance variable of @uploaders, cached at init time
85
+ # but at init time, the value of the column is not yet available
86
+ # so after init, the empty @uploaders cache must be invalidated
87
+ # it will reinitialized with the processed column value on first access
88
+ after_initialize :_set_uploaders_nil
26
89
 
27
- after_save :"store_#{column}!"
28
90
  before_save :"write_#{column}_identifier"
91
+ after_save :"store_#{column}!"
92
+ # this 'after_update' hook doesn't seem necessary, but please
93
+ # don't remove it just in case it ever becomes necessary:
94
+ after_update :"mark_remove_#{column}_false"
29
95
  after_destroy :"remove_#{column}!"
96
+ after_find :"force_retrieve_#{column}"
97
+
98
+ add_reload_callback :"force_retrieve_#{column}"
99
+
100
+ # TRYING THIS OUT FROM MONGOID:
101
+ # TODO: copy the other mongoid adapter code over
102
+ # https://github.com/carrierwaveuploader/carrierwave-mongoid/blob/master/lib/carrierwave/mongoid.rb
103
+ before_update :"store_previous_changes_for_#{column}"
104
+ after_save :"remove_previously_stored_#{column}"
30
105
 
31
106
  class_eval <<-RUBY, __FILE__, __LINE__+1
32
- def #{column}=(new_file)
33
- column = _mounter(:#{column}).serialization_column
34
- send(:attribute_will_change!, :#{column})
35
- super
36
- end
37
-
38
- def remote_#{column}_url=(url)
39
- column = _mounter(:#{column}).serialization_column
40
- send(:attribute_will_change!, :#{column})
41
- super
42
- end
43
-
44
- def remove_#{column}!
45
- super
46
- write_uploader(_mounter(:#{column}).serialization_column, nil)
47
- end
48
-
49
- def _mounter(column)
50
- @_mounters ||= {}
51
- @_mounters[column] ||= CarrierWave::Mount::Mounter.new(self, column)
52
- end
53
-
54
- def read_uploader(name)
55
- send(:attribute, name.to_s)
56
- end
57
-
58
- def write_uploader(name, value)
59
- send(:attribute=, name.to_s, value)
60
- end
61
-
62
- def reload_from_database
63
- if reloaded = self.class.load_entity(neo_id)
64
- send(:attributes=, reloaded.attributes.reject{ |k,v| v.is_a?(::CarrierWave::Uploader::Base) })
107
+
108
+ # def remote_#{column}_url=(url) is defined in 'mount_uploader'
109
+
110
+ def #{column}=(new_file)
111
+ column = _mounter(:#{column}).serialization_column
112
+ if !(new_file.blank? && __send__(:#{column}).blank?)
113
+ __send__(:"\#{column}_will_change!")
114
+ end
115
+ super
116
+ end
117
+
118
+ def remove_#{column}=(value)
119
+ column = _mounter(:#{column}).serialization_column
120
+ result = super
121
+ __send__(:"\#{column}_will_change!") if _mounter(:#{column}).remove?
122
+ result
123
+ end
124
+
125
+ def remove_#{column}!
126
+ self.remove_#{column} = true
127
+ write_#{column}_identifier
128
+ self.remove_#{column} = false
129
+ super
130
+ end
131
+
132
+ # Reset cached mounter on record reload
133
+ def reload(*)
134
+ _set_uploaders_nil
135
+ @_mounters = nil
136
+ super
137
+ end
138
+
139
+ # Reset cached mounter on record dup
140
+ def initialize_dup(other)
141
+ _set_uploaders_nil
142
+ @_mounters = nil
143
+ super
144
+ end
145
+
146
+ def _set_uploaders_nil
147
+ if @_mounters
148
+ @_mounters.each do |_, mounter|
149
+ mounter.instance_variable_set(:@uploaders, nil)
150
+ end
151
+ end
152
+ end
153
+
154
+ def _force_uploaders_reload
155
+ @_mounters.each do |_, mounter|
156
+ mounter.send(:uploaders)
157
+ end
158
+ end
159
+
160
+ # okay, this actually works:
161
+ def force_retrieve_#{column}
162
+ send(:#{column}).send(:retrieve_from_store!, #{column}_identifier)
65
163
  end
66
- reloaded
67
- end
164
+
165
+ # these produce an infinite loop, so... don't reintroduce them:
166
+ # alias_method :read_uploader, :read_attribute
167
+ # alias_method :write_uploader, :write_attribute
168
+ # public :read_uploader
169
+ # public :write_uploader
170
+
171
+ def read_uploader(name)
172
+ send(:attribute, name.to_s)
173
+ end
174
+
175
+ def write_uploader(name, value)
176
+ send(:attribute=, name.to_s, value)
177
+ end
178
+
179
+ def reload_from_database
180
+ if reloaded = self.class.load_entity(neo_id)
181
+ self.class.reload_callbacks.each { |m| reloaded.send(m) }
182
+ end
183
+ reloaded
184
+ end
185
+
186
+ def reload_from_database!
187
+ if reloaded = self.class.load_entity(neo_id)
188
+ send(:attributes=, reloaded.attributes)
189
+ self.class.reload_callbacks.each { |m| send(m) }
190
+ end
191
+ self
192
+ end
193
+
194
+ # MONGOID:
195
+ # CarrierWave 1.1 references ::ActiveRecord constant directly which
196
+ # will fail in projects without ActiveRecord. We need to overwrite this
197
+ # method to avoid it.
198
+ # See https://github.com/carrierwaveuploader/carrierwave/blob/07dc4d7bd7806ab4b963cf8acbad73d97cdfe74e/lib/carrierwave/mount.rb#L189
199
+ def store_previous_changes_for_#{column}
200
+ @_previous_changes_for_#{column} = changes[_mounter(:#{column}).serialization_column]
201
+ end
202
+
68
203
  RUBY
69
204
  end
70
- end
71
205
 
206
+
207
+ end
72
208
  end
73
209
  end
74
210
 
75
- Neo4j::ActiveNode.send :include, CarrierWave::Neo4j
211
+ Neo4j::ActiveNode.include CarrierWave::Neo4j
@@ -7,7 +7,11 @@ module CarrierWave::Neo4j
7
7
  end
8
8
 
9
9
  def to_db(value)
10
- value.identifier
10
+ if value.is_a?(Array)
11
+ value.map(&:identifier)
12
+ else
13
+ value.identifier
14
+ end
11
15
  end
12
16
 
13
17
  def to_ruby(value)
@@ -18,9 +22,15 @@ module CarrierWave::Neo4j
18
22
  end
19
23
  end
20
24
 
21
- mod = case Neo4j::VERSION.split('.').first.to_i
22
- when 3 then Neo4j
23
- when 4 then Neo4j::Shared
24
- end
25
+ def register_converter(mod)
26
+ mod::TypeConverters.send :include, CarrierWave::Neo4j::TypeConverters
27
+ end
25
28
 
26
- mod::TypeConverters.send :include, CarrierWave::Neo4j::TypeConverters
29
+ major = Neo4j::VERSION.split('.').first.to_i
30
+
31
+ case major
32
+ when 1..2 then fail('Unsupported version of Neo4j gem. Please update it.')
33
+ when 3 then register_converter(Neo4j)
34
+ when 4 then register_converter(Neo4j::Shared)
35
+ when 5..Float::INFINITY then Neo4j::Shared::TypeConverters.register_converter(CarrierWave::Neo4j::TypeConverters::UploaderConverter)
36
+ end