paper_trail 6.0.1 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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