second_level_cache 2.6.0 → 2.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/second_level_cache.rb +1 -0
- data/lib/second_level_cache/active_record/belongs_to_association.rb +3 -4
- data/lib/second_level_cache/active_record/fetch_by_uniq_key.rb +14 -15
- data/lib/second_level_cache/active_record/finder_methods.rb +36 -37
- data/lib/second_level_cache/active_record/has_one_association.rb +11 -11
- data/lib/second_level_cache/active_record/preloader.rb +14 -15
- data/lib/second_level_cache/config.rb +1 -0
- data/lib/second_level_cache/log_subscriber.rb +15 -0
- data/lib/second_level_cache/version.rb +1 -1
- data/second_level_cache.gemspec +23 -22
- data/test/active_record_test_case_helper.rb +1 -1
- data/test/model/account.rb +1 -1
- data/test/model/animal.rb +1 -1
- data/test/model/application_record.rb +3 -0
- data/test/model/book.rb +1 -1
- data/test/model/contribution.rb +1 -1
- data/test/model/image.rb +1 -1
- data/test/model/order.rb +1 -1
- data/test/model/order_item.rb +1 -1
- data/test/model/post.rb +1 -1
- data/test/model/topic.rb +1 -1
- data/test/model/user.rb +3 -3
- data/test/test_helper.rb +1 -4
- metadata +18 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0056aa765b7668e44d115f964c4fb11f1632ecf99206145c89aed0fb58f2b4d0
|
4
|
+
data.tar.gz: a4fb19d6ff3859c728c7d8a43f28f64bb092c89226772de31b5b22f1e57e2cf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32f1cb2460325a2291d2732c2f3ec906c7c16c2c5838564df7bfa56f362c0049d37c1ef2658db6c057faf31183869bbd8d6fc4702f4056f0a8bc4d143933cc68
|
7
|
+
data.tar.gz: 46e242047cd4e0c1c3651dc3e7ff03028d044a96b6c4c915d994114226c5ed30c8668248b14caac8165b51a283ba6ab9455badc5c27c6f7a31468753086216c4
|
data/CHANGELOG.md
CHANGED
data/lib/second_level_cache.rb
CHANGED
@@ -5,6 +5,7 @@ require "second_level_cache/config"
|
|
5
5
|
require "second_level_cache/record_marshal"
|
6
6
|
require "second_level_cache/record_relation"
|
7
7
|
require "second_level_cache/active_record"
|
8
|
+
require "second_level_cache/log_subscriber"
|
8
9
|
|
9
10
|
module SecondLevelCache
|
10
11
|
def self.configure
|
@@ -18,10 +18,10 @@ module SecondLevelCache
|
|
18
18
|
record = where(where_values).first
|
19
19
|
if record
|
20
20
|
SecondLevelCache.cache_store.write(cache_key, record.id)
|
21
|
-
|
21
|
+
record
|
22
22
|
else
|
23
23
|
SecondLevelCache.cache_store.delete(cache_key)
|
24
|
-
|
24
|
+
nil
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -42,21 +42,20 @@ module SecondLevelCache
|
|
42
42
|
end
|
43
43
|
|
44
44
|
private
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def cache_uniq_key(where_values)
|
46
|
+
keys = where_values.collect do |k, v|
|
47
|
+
v = Digest::MD5.hexdigest(v) if v.respond_to?(:size) && v.size >= 32
|
48
|
+
[k, v].join("_")
|
49
|
+
end
|
50
|
+
|
51
|
+
ext_key = keys.join(",")
|
52
|
+
"uniq_key_#{name}_#{ext_key}"
|
50
53
|
end
|
51
54
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def record_attributes_equal_where_values?(record, where_values)
|
57
|
-
# https://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-type_for_attribute
|
58
|
-
where_values.all? { |k, v| record&.read_attribute(k) == type_for_attribute(k).cast(v) }
|
59
|
-
end
|
55
|
+
def record_attributes_equal_where_values?(record, where_values)
|
56
|
+
# https://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-type_for_attribute
|
57
|
+
where_values.all? { |k, v| record&.read_attribute(k) == type_for_attribute(k).cast(v) }
|
58
|
+
end
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
@@ -55,49 +55,48 @@ module SecondLevelCache
|
|
55
55
|
end
|
56
56
|
|
57
57
|
private
|
58
|
+
# readonly_value - active_record/relation/query_methods.rb Rails 5.1 true/false
|
59
|
+
def cachable?
|
60
|
+
second_level_cache_enabled? &&
|
61
|
+
limit_one? &&
|
62
|
+
# !eager_loading? &&
|
63
|
+
includes_values.blank? &&
|
64
|
+
preload_values.blank? &&
|
65
|
+
eager_load_values.blank? &&
|
66
|
+
select_values.blank? &&
|
67
|
+
order_values_can_cache? &&
|
68
|
+
readonly_value.blank? &&
|
69
|
+
joins_values.blank? &&
|
70
|
+
!@klass.locking_enabled? &&
|
71
|
+
where_clause_predicates_all_equality?
|
72
|
+
end
|
58
73
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
select_values.blank? &&
|
68
|
-
order_values_can_cache? &&
|
69
|
-
readonly_value.blank? &&
|
70
|
-
joins_values.blank? &&
|
71
|
-
!@klass.locking_enabled? &&
|
72
|
-
where_clause_predicates_all_equality?
|
73
|
-
end
|
74
|
-
|
75
|
-
def order_values_can_cache?
|
76
|
-
return true if order_values.empty?
|
77
|
-
return false unless order_values.one?
|
78
|
-
return true if order_values.first == klass.primary_key
|
79
|
-
return false unless order_values.first.is_a?(::Arel::Nodes::Ordering)
|
80
|
-
return true if order_values.first.expr == klass.primary_key
|
81
|
-
order_values.first.expr.try(:name) == klass.primary_key
|
82
|
-
end
|
74
|
+
def order_values_can_cache?
|
75
|
+
return true if order_values.empty?
|
76
|
+
return false unless order_values.one?
|
77
|
+
return true if order_values.first == klass.primary_key
|
78
|
+
return false unless order_values.first.is_a?(::Arel::Nodes::Ordering)
|
79
|
+
return true if order_values.first.expr == klass.primary_key
|
80
|
+
order_values.first.expr.try(:name) == klass.primary_key
|
81
|
+
end
|
83
82
|
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
def where_clause_predicates_all_equality?
|
84
|
+
where_clause.send(:predicates).size == where_values_hash.size
|
85
|
+
end
|
87
86
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
87
|
+
def where_values_match_cache?(record)
|
88
|
+
where_values_hash.all? do |key, value|
|
89
|
+
if value.is_a?(Array)
|
90
|
+
value.include?(record.read_attribute(key))
|
91
|
+
else
|
92
|
+
record.read_attribute(key) == value
|
93
|
+
end
|
94
94
|
end
|
95
95
|
end
|
96
|
-
end
|
97
96
|
|
98
|
-
|
99
|
-
|
100
|
-
|
97
|
+
def limit_one?
|
98
|
+
limit_value.blank? || limit_value == 1
|
99
|
+
end
|
101
100
|
end
|
102
101
|
end
|
103
102
|
end
|
@@ -11,17 +11,17 @@ module SecondLevelCache
|
|
11
11
|
|
12
12
|
through = reflection.options[:through]
|
13
13
|
record = if through
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
return super unless klass.reflections[through.to_s].klass.second_level_cache_enabled?
|
15
|
+
begin
|
16
|
+
reflection.klass.find(owner.send(through).read_attribute(reflection.foreign_key))
|
17
|
+
rescue StandardError
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
else
|
21
|
+
uniq_keys = { reflection.foreign_key => owner[reflection.active_record_primary_key] }
|
22
|
+
uniq_keys[reflection.type] = owner.class.base_class.name if reflection.options[:as]
|
23
|
+
klass.fetch_by_uniq_keys(uniq_keys)
|
24
|
+
end
|
25
25
|
|
26
26
|
return nil unless record
|
27
27
|
record.tap { |r| set_inverse_instance(r) }
|
@@ -15,23 +15,23 @@ module SecondLevelCache
|
|
15
15
|
records_from_cache = ::SecondLevelCache.cache_store.read_multi(*map_cache_keys)
|
16
16
|
|
17
17
|
record_marshals = if RAILS6
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
RecordMarshal.load_multi(records_from_cache.values) do |record|
|
19
|
+
# This block is copy from:
|
20
|
+
# https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/associations/preloader/association.rb#L101
|
21
|
+
owner = owners_by_key[convert_key(record[association_key_name])].first
|
22
|
+
association = owner.association(reflection.name)
|
23
|
+
association.set_inverse_instance(record)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
RecordMarshal.load_multi(records_from_cache.values, &block)
|
27
|
+
end
|
28
28
|
|
29
29
|
# NOTICE
|
30
30
|
# Rails.cache.read_multi return hash that has keys only hitted.
|
31
31
|
# eg. Rails.cache.read_multi(1,2,3) => {2 => hit_value, 3 => hit_value}
|
32
32
|
hitted_ids = record_marshals.map { |record| record.read_attribute(association_key_name).to_s }
|
33
33
|
missed_ids = ids.map(&:to_s) - hitted_ids
|
34
|
-
::
|
34
|
+
ActiveSupport::Notifications.instrument("preload.second_level_cache", key: association_key_name, hit: hitted_ids, miss: missed_ids)
|
35
35
|
return SecondLevelCache::RecordRelation.new(record_marshals) if missed_ids.empty?
|
36
36
|
|
37
37
|
records_from_db = super(missed_ids, &block)
|
@@ -41,10 +41,9 @@ module SecondLevelCache
|
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
44
|
+
def write_cache(record)
|
45
|
+
record.write_second_level_cache
|
46
|
+
end
|
48
47
|
end
|
49
48
|
end
|
50
49
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SecondLevelCache
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
|
+
# preload.second_level_cache
|
6
|
+
def preload(event)
|
7
|
+
prefix = color("SecondLevelCache", CYAN)
|
8
|
+
miss_ids = (event.payload[:miss] || []).join(",")
|
9
|
+
hit_ids = (event.payload[:hit] || []).join(",")
|
10
|
+
debug " #{prefix} preload #{event.payload[:key]} miss [#{miss_ids}], hit [#{hit_ids}]"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
SecondLevelCache::LogSubscriber.attach_to :second_level_cache
|
data/second_level_cache.gemspec
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path("../lib/second_level_cache/version", __FILE__)
|
4
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
|
6
7
|
Gem::Specification.new do |gem|
|
7
|
-
gem.authors = [
|
8
|
-
gem.email = [
|
9
|
-
gem.description =
|
8
|
+
gem.authors = ["Hooopo"]
|
9
|
+
gem.email = ["hoooopo@gmail.com"]
|
10
|
+
gem.description = "Write Through and Read Through caching library inspired by CacheMoney and cache_fu, support ActiveRecord 4."
|
10
11
|
gem.summary = <<-SUMMARY
|
11
12
|
SecondLevelCache is a write-through and read-through caching library inspired by Cache Money and cache_fu, support only Rails3 and ActiveRecord.
|
12
13
|
|
@@ -15,26 +16,26 @@ Gem::Specification.new do |gem|
|
|
15
16
|
Write-Through: As objects are created, updated, and deleted, all of the caches are automatically kept up-to-date and coherent.
|
16
17
|
SUMMARY
|
17
18
|
|
18
|
-
gem.homepage =
|
19
|
+
gem.homepage = "https://github.com/hooopo/second_level_cache"
|
19
20
|
|
20
|
-
gem.files = Dir.glob(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
gem.files = Dir.glob("lib/**/*.rb") + [
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"Gemfile",
|
25
|
+
"CHANGELOG.md",
|
26
|
+
"second_level_cache.gemspec"
|
26
27
|
]
|
27
|
-
gem.test_files = Dir.glob(
|
28
|
+
gem.test_files = Dir.glob("test/**/*.rb")
|
28
29
|
gem.executables = gem.files.grep(%r{^bin/})
|
29
|
-
gem.name =
|
30
|
-
gem.require_paths = [
|
30
|
+
gem.name = "second_level_cache"
|
31
|
+
gem.require_paths = ["lib"]
|
31
32
|
gem.version = SecondLevelCache::VERSION
|
32
33
|
|
33
|
-
gem.add_runtime_dependency
|
34
|
-
gem.add_runtime_dependency
|
34
|
+
gem.add_runtime_dependency "activerecord", [">= 5.2", "< 7"]
|
35
|
+
gem.add_runtime_dependency "activesupport", [">= 5.2", "< 7"]
|
35
36
|
|
36
|
-
gem.add_development_dependency
|
37
|
-
gem.add_development_dependency
|
38
|
-
gem.add_development_dependency
|
39
|
-
gem.add_development_dependency
|
37
|
+
gem.add_development_dependency "database_cleaner"
|
38
|
+
gem.add_development_dependency "rake"
|
39
|
+
gem.add_development_dependency "rubocop"
|
40
|
+
gem.add_development_dependency "sqlite3", "> 1.4"
|
40
41
|
end
|
data/test/model/account.rb
CHANGED
@@ -7,7 +7,7 @@ ActiveRecord::Base.connection.create_table(:accounts, force: true) do |t|
|
|
7
7
|
t.timestamps null: false
|
8
8
|
end
|
9
9
|
|
10
|
-
class Account <
|
10
|
+
class Account < ApplicationRecord
|
11
11
|
second_level_cache expires_in: 3.days
|
12
12
|
belongs_to :user, foreign_key: :user_id, inverse_of: :account
|
13
13
|
end
|
data/test/model/animal.rb
CHANGED
data/test/model/book.rb
CHANGED
@@ -10,7 +10,7 @@ ActiveRecord::Base.connection.create_table(:books, force: true) do |t|
|
|
10
10
|
t.boolean :normal, default: true, nil: false
|
11
11
|
end
|
12
12
|
|
13
|
-
class Book <
|
13
|
+
class Book < ApplicationRecord
|
14
14
|
second_level_cache
|
15
15
|
|
16
16
|
default_scope -> { where(normal: true) }
|
data/test/model/contribution.rb
CHANGED
@@ -6,7 +6,7 @@ ActiveRecord::Base.connection.create_table(:contributions, force: true) do |t|
|
|
6
6
|
t.date :date
|
7
7
|
end
|
8
8
|
|
9
|
-
class Contribution <
|
9
|
+
class Contribution < ApplicationRecord
|
10
10
|
second_level_cache
|
11
11
|
|
12
12
|
validates_uniqueness_of :user_id, scope: :date, if: -> { user_id_changed? || date_changed? }
|
data/test/model/image.rb
CHANGED
data/test/model/order.rb
CHANGED
data/test/model/order_item.rb
CHANGED
data/test/model/post.rb
CHANGED
data/test/model/topic.rb
CHANGED
data/test/model/user.rb
CHANGED
@@ -26,7 +26,7 @@ ActiveRecord::Base.connection.create_table(:namespaces, force: true) do |t|
|
|
26
26
|
t.timestamps null: false
|
27
27
|
end
|
28
28
|
|
29
|
-
class User <
|
29
|
+
class User < ApplicationRecord
|
30
30
|
CACHE_VERSION = 3
|
31
31
|
second_level_cache(version: CACHE_VERSION, expires_in: 3.days)
|
32
32
|
acts_as_paranoid
|
@@ -46,13 +46,13 @@ class User < ActiveRecord::Base
|
|
46
46
|
enum status: %i[active archived]
|
47
47
|
end
|
48
48
|
|
49
|
-
class Namespace <
|
49
|
+
class Namespace < ApplicationRecord
|
50
50
|
second_level_cache version: 1, expires_in: 3.days
|
51
51
|
|
52
52
|
belongs_to :user
|
53
53
|
end
|
54
54
|
|
55
|
-
class ForkedUserLink <
|
55
|
+
class ForkedUserLink < ApplicationRecord
|
56
56
|
second_level_cache version: 1, expires_in: 1.day
|
57
57
|
|
58
58
|
belongs_to :forked_from_user, class_name: "User"
|
data/test/test_helper.rb
CHANGED
@@ -16,6 +16,7 @@ require "second_level_cache"
|
|
16
16
|
|
17
17
|
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
18
18
|
|
19
|
+
require "model/application_record"
|
19
20
|
require "model/user"
|
20
21
|
require "model/book"
|
21
22
|
require "model/image"
|
@@ -33,10 +34,6 @@ SecondLevelCache.configure do |config|
|
|
33
34
|
config.cache_store = ActiveSupport::Cache::MemoryStore.new
|
34
35
|
end
|
35
36
|
|
36
|
-
SecondLevelCache.logger.level = Logger::INFO
|
37
|
-
ActiveSupport::Cache::MemoryStore.logger = SecondLevelCache.logger
|
38
|
-
ActiveRecord::Base.logger = SecondLevelCache.logger
|
39
|
-
|
40
37
|
module ActiveSupport
|
41
38
|
class TestCase
|
42
39
|
setup do
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: second_level_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.6.
|
4
|
+
version: 2.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hooopo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -31,7 +31,7 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '7'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
@@ -51,19 +51,19 @@ dependencies:
|
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '7'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
|
-
name:
|
54
|
+
name: database_cleaner
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- - "
|
57
|
+
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: '
|
59
|
+
version: '0'
|
60
60
|
type: :development
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
|
-
- - "
|
64
|
+
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
66
|
+
version: '0'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: rake
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,7 +79,7 @@ dependencies:
|
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
|
-
name:
|
82
|
+
name: rubocop
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
85
|
- - ">="
|
@@ -93,19 +93,19 @@ dependencies:
|
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
96
|
+
name: sqlite3
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
|
-
- - "
|
99
|
+
- - ">"
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: '1.4'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
|
-
- - "
|
106
|
+
- - ">"
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
108
|
+
version: '1.4'
|
109
109
|
description: Write Through and Read Through caching library inspired by CacheMoney
|
110
110
|
and cache_fu, support ActiveRecord 4.
|
111
111
|
email:
|
@@ -129,6 +129,7 @@ files:
|
|
129
129
|
- lib/second_level_cache/active_record/persistence.rb
|
130
130
|
- lib/second_level_cache/active_record/preloader.rb
|
131
131
|
- lib/second_level_cache/config.rb
|
132
|
+
- lib/second_level_cache/log_subscriber.rb
|
132
133
|
- lib/second_level_cache/mixin.rb
|
133
134
|
- lib/second_level_cache/record_marshal.rb
|
134
135
|
- lib/second_level_cache/record_relation.rb
|
@@ -143,6 +144,7 @@ files:
|
|
143
144
|
- test/has_one_association_test.rb
|
144
145
|
- test/model/account.rb
|
145
146
|
- test/model/animal.rb
|
147
|
+
- test/model/application_record.rb
|
146
148
|
- test/model/book.rb
|
147
149
|
- test/model/contribution.rb
|
148
150
|
- test/model/image.rb
|
@@ -211,6 +213,7 @@ test_files:
|
|
211
213
|
- test/model/topic.rb
|
212
214
|
- test/model/animal.rb
|
213
215
|
- test/model/order.rb
|
216
|
+
- test/model/application_record.rb
|
214
217
|
- test/model/post.rb
|
215
218
|
- test/model/user.rb
|
216
219
|
- test/fetch_by_uniq_key_test.rb
|