paper_trail 6.0.1 → 6.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,7 @@
1
1
  require "active_support/concern"
2
2
  require "paper_trail/attribute_serializers/object_changes_attribute"
3
+ require "paper_trail/queries/versions/where_object"
4
+ require "paper_trail/queries/versions/where_object_changes"
3
5
 
4
6
  module PaperTrail
5
7
  # Originally, PaperTrail did not provide this module, and all of this
@@ -95,62 +97,60 @@ module PaperTrail
95
97
  end
96
98
  end
97
99
 
98
- # Query the `versions.objects` column using the SQL LIKE operator.
99
- # Performs an attribute search on the serialized object by invoking the
100
- # identically-named method in the serializer being used.
100
+ # Given a hash of attributes like `name: 'Joan'`, query the
101
+ # `versions.objects` column.
102
+ #
103
+ # ```
104
+ # SELECT "versions".*
105
+ # FROM "versions"
106
+ # WHERE ("versions"."object" LIKE '%
107
+ # name: Joan
108
+ # %')
109
+ # ```
110
+ #
111
+ # This is useful for finding versions where a given attribute had a given
112
+ # value. Imagine, in the example above, that Joan had changed her name
113
+ # and we wanted to find the versions before that change.
114
+ #
115
+ # Based on the data type of the `object` column, the appropriate SQL
116
+ # operator is used. For example, a text column will use `like`, and a
117
+ # jsonb column will use `@>`.
118
+ #
101
119
  # @api public
102
120
  def where_object(args = {})
103
121
  raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
104
-
105
- if columns_hash["object"].type == :jsonb
106
- where("object @> ?", args.to_json)
107
- elsif columns_hash["object"].type == :json
108
- predicates = []
109
- values = []
110
- args.each do |field, value|
111
- predicates.push "object->>? = ?"
112
- values.concat([field, value.to_s])
113
- end
114
- sql = predicates.join(" and ")
115
- where(sql, *values)
116
- else
117
- arel_field = arel_table[:object]
118
- where_conditions = args.map { |field, value|
119
- PaperTrail.serializer.where_object_condition(arel_field, field, value)
120
- }
121
- where_conditions = where_conditions.reduce { |a, e| a.and(e) }
122
- where(where_conditions)
123
- end
122
+ Queries::Versions::WhereObject.new(self, args).execute
124
123
  end
125
124
 
126
- # Query the `versions.object_changes` column by attributes, using the
127
- # SQL LIKE operator.
125
+ # Given a hash of attributes like `name: 'Joan'`, query the
126
+ # `versions.objects_changes` column.
127
+ #
128
+ # ```
129
+ # SELECT "versions".*
130
+ # FROM "versions"
131
+ # WHERE .. ("versions"."object_changes" LIKE '%
132
+ # name:
133
+ # - Joan
134
+ # %' OR "versions"."object_changes" LIKE '%
135
+ # name:
136
+ # -%
137
+ # - Joan
138
+ # %')
139
+ # ```
140
+ #
141
+ # This is useful for finding versions immediately before and after a given
142
+ # attribute had a given value. Imagine, in the example above, that someone
143
+ # changed their name to Joan and we wanted to find the versions
144
+ # immediately before and after that change.
145
+ #
146
+ # Based on the data type of the `object` column, the appropriate SQL
147
+ # operator is used. For example, a text column will use `like`, and a
148
+ # jsonb column will use `@>`.
149
+ #
128
150
  # @api public
129
151
  def where_object_changes(args = {})
130
152
  raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
131
-
132
- if columns_hash["object_changes"].type == :jsonb
133
- args.each { |field, value| args[field] = [value] }
134
- where("object_changes @> ?", args.to_json)
135
- elsif columns_hash["object"].type == :json
136
- predicates = []
137
- values = []
138
- args.each do |field, value|
139
- predicates.push(
140
- "((object_changes->>? ILIKE ?) OR (object_changes->>? ILIKE ?))"
141
- )
142
- values.concat([field, "[#{value.to_json},%", field, "[%,#{value.to_json}]%"])
143
- end
144
- sql = predicates.join(" and ")
145
- where(sql, *values)
146
- else
147
- arel_field = arel_table[:object_changes]
148
- where_conditions = args.map { |field, value|
149
- PaperTrail.serializer.where_object_changes_condition(arel_field, field, value)
150
- }
151
- where_conditions = where_conditions.reduce { |a, e| a.and(e) }
152
- where(where_conditions)
153
- end
153
+ Queries::Versions::WhereObjectChanges.new(self, args).execute
154
154
  end
155
155
 
156
156
  def primary_key_is_int?
@@ -3,7 +3,7 @@ module PaperTrail
3
3
  module VERSION
4
4
  MAJOR = 6
5
5
  MINOR = 0
6
- TINY = 1
6
+ TINY = 2
7
7
  PRE = nil
8
8
 
9
9
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".").freeze
@@ -5,8 +5,12 @@ Gem::Specification.new do |s|
5
5
  s.name = "paper_trail"
6
6
  s.version = PaperTrail::VERSION::STRING.dup # The `dup` is for ruby 1.9.3
7
7
  s.platform = Gem::Platform::RUBY
8
- s.summary = "Track changes to your models' data. Good for auditing or versioning."
9
- s.description = s.summary
8
+ s.summary = "Track changes to your models."
9
+ s.description = <<-EOS
10
+ Track changes to your models, for auditing or versioning. See how a model looked
11
+ at any stage in its lifecycle, revert it to any version, or restore it after it
12
+ has been destroyed.
13
+ EOS
10
14
  s.homepage = "https://github.com/airblade/paper_trail"
11
15
  s.authors = ["Andy Stewart", "Ben Atkins"]
12
16
  s.email = "batkinz@gmail.com"
@@ -28,15 +32,31 @@ Gem::Specification.new do |s|
28
32
  s.add_development_dependency "rake", "~> 10.4.2"
29
33
  s.add_development_dependency "shoulda", "~> 3.5.0"
30
34
  s.add_development_dependency "ffaker", "~> 2.1.0"
31
- s.add_development_dependency "railties", [">= 3.0", "< 6.0"]
35
+
36
+ # Why `railties`? Possibly used by `test/dummy` boot up?
37
+ s.add_development_dependency "railties", [">= 4.0", "< 5.2"]
38
+
32
39
  s.add_development_dependency "rack-test", "~> 0.6.3"
33
40
  s.add_development_dependency "rspec-rails", "~> 3.5"
34
41
  s.add_development_dependency "generator_spec", "~> 0.9.3"
35
42
  s.add_development_dependency "database_cleaner", "~> 1.2"
36
43
  s.add_development_dependency "pry-nav", "~> 0.2.4"
44
+
45
+ # We cannot upgrade rubocop until we drop support for ruby 1.9.3.
46
+ # Rubocop 0.42 requires ruby >= 2.0. We could add a conditional, as we do
47
+ # below for rack and pg, but that means our config files (e.g. `.rubocop.yml`
48
+ # would have to simultaneously be valid in two different versions of rubocop.
49
+ # That is currently possible, but probably won't be in the future, and is
50
+ # not worth the effort.) Because of pain points like this, I think we'll
51
+ # have to drop support for ruby 1.9.3 soon.
37
52
  s.add_development_dependency "rubocop", "~> 0.41.1"
53
+
38
54
  s.add_development_dependency "timecop", "~> 0.8.0"
39
55
 
56
+ if ::Gem.ruby_version < ::Gem::Version.new("2.0.0")
57
+ s.add_development_dependency "rack", "< 2"
58
+ end
59
+
40
60
  if defined?(JRUBY_VERSION)
41
61
  s.add_development_dependency "activerecord-jdbcsqlite3-adapter", "~> 1.3.15"
42
62
  s.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 1.3.15"
@@ -0,0 +1,28 @@
1
+ require "rails_helper"
2
+
3
+ RSpec.describe ArticlesController, type: :controller do
4
+ describe "PaperTrail.enabled_for_controller?" do
5
+ context "PaperTrail.enabled? == true" do
6
+ before { PaperTrail.enabled = true }
7
+
8
+ it "returns true" do
9
+ assert PaperTrail.enabled?
10
+ post :create, params_wrapper(article: { title: "Doh", content: FFaker::Lorem.sentence })
11
+ expect(assigns(:article)).to_not be_nil
12
+ assert PaperTrail.enabled_for_controller?
13
+ assert_equal 1, assigns(:article).versions.length
14
+ end
15
+
16
+ after { PaperTrail.enabled = false }
17
+ end
18
+
19
+ context "PaperTrail.enabled? == false" do
20
+ it "returns false" do
21
+ assert !PaperTrail.enabled?
22
+ post :create, params_wrapper(article: { title: "Doh", content: FFaker::Lorem.sentence })
23
+ assert !PaperTrail.enabled_for_controller?
24
+ assert_equal 0, assigns(:article).versions.length
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,10 +1,24 @@
1
1
  require "rubygems"
2
- gemfile = File.expand_path("../../../../Gemfile", __FILE__)
3
2
 
4
- if File.exist?(gemfile)
5
- ENV["BUNDLE_GEMFILE"] = gemfile
6
- require "bundler"
7
- Bundler.setup
3
+ # We normally use the root project Gemfile (and gemspec), but when we run rake
4
+ # locally (not on travis) in this dummy app, we set the BUNDLE_GEMFILE env.
5
+ # variable. The project Gemfile/gemspec allows AR 4.0, which is a problem
6
+ # because this dummy app uses `enum` in some of its models, and `enum` was
7
+ # introduced in AR 4.1. So, when we run rake here, we use:
8
+ #
9
+ # BUNDLE_GEMFILE=../../gemfiles/ar_4.2.gemfile bundle exec rake
10
+ #
11
+ # Once we drop support for AR 4.0 and 4.1 this will be less of a problem, but
12
+ # we should keep the ability to specify BUNDLE_GEMFILE because the same
13
+ # situation could come up in the future.
14
+ unless ENV.key?("BUNDLE_GEMFILE")
15
+ gemfile = File.expand_path("../../../../Gemfile", __FILE__)
16
+ if File.exist?(gemfile)
17
+ puts "Booting PT test dummy app: Using gemfile: #{gemfile}"
18
+ ENV["BUNDLE_GEMFILE"] = gemfile
19
+ end
8
20
  end
21
+ require "bundler"
22
+ Bundler.setup
9
23
 
10
- $LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
24
+ $LOAD_PATH.unshift(File.expand_path("../../../../lib", __FILE__))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.1
4
+ version: 6.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Stewart
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-04 00:00:00.000000000 Z
12
+ date: 2016-12-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -107,20 +107,20 @@ dependencies:
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '3.0'
110
+ version: '4.0'
111
111
  - - "<"
112
112
  - !ruby/object:Gem::Version
113
- version: '6.0'
113
+ version: '5.2'
114
114
  type: :development
115
115
  prerelease: false
116
116
  version_requirements: !ruby/object:Gem::Requirement
117
117
  requirements:
118
118
  - - ">="
119
119
  - !ruby/object:Gem::Version
120
- version: '3.0'
120
+ version: '4.0'
121
121
  - - "<"
122
122
  - !ruby/object:Gem::Version
123
- version: '6.0'
123
+ version: '5.2'
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: rack-test
126
126
  requirement: !ruby/object:Gem::Requirement
@@ -261,7 +261,10 @@ dependencies:
261
261
  - - "~>"
262
262
  - !ruby/object:Gem::Version
263
263
  version: 0.4.2
264
- description: Track changes to your models' data. Good for auditing or versioning.
264
+ description: |
265
+ Track changes to your models, for auditing or versioning. See how a model looked
266
+ at any stage in its lifecycle, revert it to any version, or restore it after it
267
+ has been destroyed.
265
268
  email: batkinz@gmail.com
266
269
  executables: []
267
270
  extensions: []
@@ -313,6 +316,8 @@ files:
313
316
  - lib/paper_trail/frameworks/sinatra.rb
314
317
  - lib/paper_trail/has_paper_trail.rb
315
318
  - lib/paper_trail/model_config.rb
319
+ - lib/paper_trail/queries/versions/where_object.rb
320
+ - lib/paper_trail/queries/versions/where_object_changes.rb
316
321
  - lib/paper_trail/record_history.rb
317
322
  - lib/paper_trail/record_trail.rb
318
323
  - lib/paper_trail/reifier.rb
@@ -322,6 +327,7 @@ files:
322
327
  - lib/paper_trail/version_concern.rb
323
328
  - lib/paper_trail/version_number.rb
324
329
  - paper_trail.gemspec
330
+ - spec/controllers/articles_controller_spec.rb
325
331
  - spec/generators/install_generator_spec.rb
326
332
  - spec/generators/paper_trail/templates/create_versions_spec.rb
327
333
  - spec/models/animal_spec.rb
@@ -425,7 +431,6 @@ files:
425
431
  - test/dummy/db/migrate/20110208155312_set_up_test_tables.rb
426
432
  - test/dummy/db/schema.rb
427
433
  - test/functional/controller_test.rb
428
- - test/functional/enabled_for_controller_test.rb
429
434
  - test/functional/modular_sinatra_test.rb
430
435
  - test/functional/sinatra_test.rb
431
436
  - test/functional/thread_safety_test.rb
@@ -461,11 +466,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
461
466
  version: 1.3.6
462
467
  requirements: []
463
468
  rubyforge_project:
464
- rubygems_version: 2.5.1
469
+ rubygems_version: 2.5.2
465
470
  signing_key:
466
471
  specification_version: 4
467
- summary: Track changes to your models' data. Good for auditing or versioning.
472
+ summary: Track changes to your models.
468
473
  test_files:
474
+ - spec/controllers/articles_controller_spec.rb
469
475
  - spec/generators/install_generator_spec.rb
470
476
  - spec/generators/paper_trail/templates/create_versions_spec.rb
471
477
  - spec/models/animal_spec.rb
@@ -569,7 +575,6 @@ test_files:
569
575
  - test/dummy/db/migrate/20110208155312_set_up_test_tables.rb
570
576
  - test/dummy/db/schema.rb
571
577
  - test/functional/controller_test.rb
572
- - test/functional/enabled_for_controller_test.rb
573
578
  - test/functional/modular_sinatra_test.rb
574
579
  - test/functional/sinatra_test.rb
575
580
  - test/functional/thread_safety_test.rb
@@ -1,28 +0,0 @@
1
- require "test_helper"
2
-
3
- class EnabledForControllerTest < ActionController::TestCase
4
- tests ArticlesController
5
-
6
- context "`PaperTrail.enabled? == true`" do
7
- should "enabled_for_controller?.should == true" do
8
- assert PaperTrail.enabled?
9
- post :create, params_wrapper(article: { title: "Doh", content: FFaker::Lorem.sentence })
10
- assert_not_nil assigns(:article)
11
- assert PaperTrail.enabled_for_controller?
12
- assert_equal 1, assigns(:article).versions.length
13
- end
14
- end
15
-
16
- context "`PaperTrail.enabled? == false`" do
17
- setup { PaperTrail.enabled = false }
18
-
19
- should "enabled_for_controller?.should == false" do
20
- assert !PaperTrail.enabled?
21
- post :create, params_wrapper(article: { title: "Doh", content: FFaker::Lorem.sentence })
22
- assert !PaperTrail.enabled_for_controller?
23
- assert_equal 0, assigns(:article).versions.length
24
- end
25
-
26
- teardown { PaperTrail.enabled = true }
27
- end
28
- end