better_record 0.7.0 → 0.7.1

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
2
  SHA256:
3
- metadata.gz: c4e3bcdf03926a87f91b4b0b55b8c34f686142904671b0434ae92fec0e4a5ced
4
- data.tar.gz: 1a87533db8f024b44e0cc0c159ecd8392d91c96ee66094b51f7dedc606ea10e1
3
+ metadata.gz: fdba9a47098a0a01e86fcaebd7c82c5d2c896dec9b8d7df67c3235f26c94b495
4
+ data.tar.gz: a05cbc82c831fbf2d063355afe66c66bf4404432af3e78c89baf625f1eba530d
5
5
  SHA512:
6
- metadata.gz: ad743dbfece1c278d146ae8bffdc8ae9d924f97b8214e13834f1161a0bb49b5fd4dcc52487d7aacc0b8263660eb34ced8fc460d374f2622789f272dc49e8dcf4
7
- data.tar.gz: 1deddcfcb7b45e90cfdef429b0413db7e1d35685524c09a8c1c375d604a7706748a36b7f4cf8dbbcf22bb18c7fc3c6a802a377d188c9013f85509054f5afa355
6
+ metadata.gz: 294de3be50905c60b2ccfa414a1a3d362d46b7ce9a1dd088581c7d4069eed8bfe85685aab234893bd793aea2dc0d1a9f4b437d2617b59398a12ccb54985598e0
7
+ data.tar.gz: 4f7e75b61f6831e27fe088c04aea60918ffbf019dfa823bdadb0e33e4508c54239a4856ff18e9b5f7dcf11a351febbc5c3526482ab9a6c9b81fc30d28854e1df
@@ -9,157 +9,23 @@ module BetterRecord
9
9
  # == Extensions ===========================================================
10
10
 
11
11
  # == Relationships ========================================================
12
-
12
+ if (ha = BetterRecord.has_auditing_relation_by_default)
13
+ has_many self.audit_relation_name,
14
+ class_name: 'BetterRecord::LoggedAction',
15
+ primary_type: :table_name,
16
+ foreign_key: :row_id,
17
+ foreign_type: :table_name,
18
+ as: self.audit_relation_name
19
+ end
13
20
  # == Validations ==========================================================
14
- before_validation :set_booleans
15
21
 
16
22
  # == Scopes ===============================================================
17
23
 
18
24
  # == Callbacks ============================================================
19
25
 
20
26
  # == Class Methods ========================================================
21
- def self.audit_relation_name
22
- @@audit_relation_name ||= (BetterRecord.audit_relation_name.presence || :audits).to_sym
23
- end
24
-
25
- def self.boolean_columns
26
- []
27
- end
28
-
29
- def self.column_comments(prefix = '')
30
- longest_name = 0
31
- column_names.each {|nm| longest_name = nm.length if nm.length > longest_name}
32
- longest_name += 1
33
- str = ''
34
- columns.each do |col|
35
- unless col.name == 'id'
36
- spaces = "#{' ' * (longest_name - col.name.length)}"
37
- is_required = "#{col.null == false ? ', required' : ''}"
38
- is_default = "#{col.default ? ", default: #{col.default}" : ''}"
39
- str << "#{prefix}##{spaces}#{col.name}: :#{col.type}#{is_required}\n"
40
- end
41
- end
42
- str
43
- end
44
-
45
- def self.default_print
46
- column_names
47
- end
48
-
49
- def self.find_or_retry_by(*args)
50
- found = nil
51
- retries = 0
52
- begin
53
- raise ActiveRecord::RecordNotFound unless found = find_by(*args)
54
- return found
55
- rescue
56
- sleep retries += 1
57
- retry if (retries) < 5
58
- end
59
- found
60
- end
61
-
62
- def self.queue_adapter_inline?
63
- @@queue_adapter ||= Rails.application.config.active_job.queue_adapter
64
- @@queue_adapter == :inline
65
- end
66
-
67
- def self.table_name_has_schema?
68
- @@table_name_has_schema ||= (table_name =~ /\w+\.\w+/)
69
- end
70
-
71
- def self.table_name_without_schema
72
- @@table_name_without_schema ||= (table_name =~ /\w+\.\w+/) ? table_name.split('.').last : table_name
73
- end
74
-
75
- def self.table_schema
76
- @@table_schema ||= table_name_has_schema? ? table_name.split('.').first : 'public'
77
- end
78
-
79
- def self.table_size
80
- BetterRecord::TableSize.unscoped.find_by(name: table_name_without_schema, schema: table_schema)
81
- end
82
-
83
- def self.transaction(*args)
84
- super(*args) do
85
- if Current.user
86
- ip = Current.ip_address ? "'#{Current.ip_address}'" : 'NULL'
87
-
88
- ActiveRecord::Base.connection.execute <<-SQL
89
- CREATE TEMP TABLE IF NOT EXISTS
90
- "_app_user" (user_id integer, user_type text, ip_address inet);
91
-
92
- UPDATE
93
- _app_user
94
- SET
95
- user_id=#{Current.user.id},
96
- user_type='#{Current.user.class.to_s}',
97
- ip_address=#{ip};
98
-
99
- INSERT INTO
100
- _app_user (user_id, user_type, ip_address)
101
- SELECT
102
- #{Current.user.id},
103
- '#{Current.user.class.to_s}',
104
- #{ip}
105
- WHERE NOT EXISTS (SELECT * FROM _app_user);
106
- SQL
107
- end
108
-
109
- yield
110
- end
111
- end
112
27
 
113
28
  # == Instance Methods =====================================================
114
- def queue_adapter_inline?
115
- self.class.queue_adapter_inline?
116
- end
117
-
118
- %w(path url).each do |cat|
119
- self.__send__ :define_method, :"rails_blob_#{cat}" do |*args|
120
- Rails.application.routes.url_helpers.__send__ :"rails_blob_#{cat}", *args
121
- end
122
- end
123
29
 
124
- def purge(attached)
125
- attached.__send__ queue_adapter_inline? ? :purge : :purge_later
126
- end
127
-
128
- def boolean_columns
129
- self.class.boolean_columns
130
- end
131
-
132
- def default_print
133
- self.class.default_print
134
- end
135
-
136
- private
137
- # def table_name_has_schema?
138
- # self.class.table_name_has_schema?
139
- # end
140
- #
141
- # def table_schema
142
- # self.class.table_schema
143
- # end
144
- #
145
- # def table_name_without_schema
146
- # self.class.table_name_without_schema
147
- # end
148
-
149
- def set_booleans
150
- self.class.boolean_columns.each do |nm|
151
- self.__send__("#{nm}=", __send__("#{nm}=", !!Boolean.parse(__send__ nm)))
152
- end
153
- true
154
- end
155
-
156
- if (ha = BetterRecord.has_audits_by_default)
157
- has_many self.audit_relation_name,
158
- class_name: 'BetterRecord::LoggedAction',
159
- primary_type: :table_name,
160
- foreign_key: :row_id,
161
- foreign_type: :table_name,
162
- as: self.audit_relation_name
163
- end
164
30
  end
165
31
  end
@@ -0,0 +1,3 @@
1
+ Dir.glob(BetterRecord::Engine.root.join('lib', 'better_record', 'concerns', '**', '*.rb')).each do |d|
2
+ require d
3
+ end
data/lib/better_record.rb CHANGED
@@ -1,19 +1,23 @@
1
1
  require "active_support"
2
2
  require "active_record"
3
3
 
4
+ Dir.glob("#{File.expand_path(__dir__)}/core_ext/*.rb").each do |d|
5
+ require d
6
+ end
7
+
4
8
  module BetterRecord
5
9
  class << self
6
10
  attr_accessor :default_polymorphic_method,
7
11
  :db_audit_schema,
8
- :has_audits_by_default,
12
+ :has_auditing_relation_by_default,
9
13
  :audit_relation_name,
10
14
  :layout_template,
11
15
  :app_domain_name
12
16
  end
13
17
  self.default_polymorphic_method = (ENV.fetch('BR_DEFAULT_POLYMORPHIC_METHOD') { :polymorphic_name }).to_sym
14
18
  self.db_audit_schema = ENV.fetch('BR_DB_AUDIT_SCHEMA') { 'auditing' }
15
- self.has_audits_by_default = ActiveRecord::Type::Boolean.new.cast(ENV.fetch('BR_ADD_HAS_MANY') { false })
16
- self.audit_relation_name = (ENV.fetch('BR_AUDIT_RELATION_NAME') { 'audits' }).to_sym
19
+ self.has_auditing_relation_by_default = ActiveRecord::Type::Boolean.new.cast(ENV.fetch('BR_ADD_HAS_MANY') { true })
20
+ self.audit_relation_name = (ENV.fetch('BR_AUDIT_RELATION_NAME') { 'logged_actions' }).to_sym
17
21
  self.layout_template = (ENV.fetch('BR_LAYOUT_TEMPLATE') { 'better_record/layout' }).to_s
18
22
  self.app_domain_name = (ENV.fetch('APP_DOMAIN_NAME') { 'non_existant_domain.com' }).to_s
19
23
  end
@@ -1,24 +1,30 @@
1
- module ActiveRecord
2
- module Associations
3
- class AssociationScope #:nodoc:
4
- def self.get_bind_values(owner, chain)
5
- binds = []
6
- last_reflection = chain.last
1
+ require 'active_support/concern'
2
+ require 'active_record/associations'
3
+ require 'active_record/associations/association_scope'
7
4
 
8
- binds << last_reflection.join_id_for(owner)
9
- if last_reflection.type
10
- binds << BetterRecord::PolymorphicOverride.polymorphic_value(owner.class, last_reflection.options.presence)
11
- end
5
+ module BetterRecord
6
+ module AssociationsExtensions
7
+ module AssociationScopeExtensions
8
+ extend ActiveSupport::Concern
12
9
 
13
- chain.each_cons(2).each do |reflection, next_reflection|
14
- if reflection.type
15
- binds << BetterRecord::PolymorphicOverride.polymorphic_value(next_reflection.klass, (reflection.options[:primary_type].present? ? reflection.options : next_reflection.options))
10
+ included do
11
+ def self.get_bind_values(owner, chain)
12
+ binds = []
13
+ last_reflection = chain.last
14
+
15
+ binds << last_reflection.join_id_for(owner)
16
+ if last_reflection.type
17
+ binds << BetterRecord::PolymorphicOverride.polymorphic_value(owner.class, last_reflection.options.presence)
18
+ end
19
+
20
+ chain.each_cons(2).each do |reflection, next_reflection|
21
+ if reflection.type
22
+ binds << BetterRecord::PolymorphicOverride.polymorphic_value(next_reflection.klass, (reflection.options[:primary_type].present? ? reflection.options : next_reflection.options))
23
+ end
16
24
  end
25
+ binds
17
26
  end
18
- binds
19
- end
20
27
 
21
- private
22
28
  def last_chain_scope(scope, reflection, owner)
23
29
  join_keys = reflection.join_keys
24
30
  key = join_keys.key
@@ -36,6 +42,7 @@ module ActiveRecord
36
42
  scope
37
43
  end
38
44
 
45
+
39
46
  def next_chain_scope(scope, reflection, next_reflection)
40
47
  join_keys = reflection.join_keys
41
48
  key = join_keys.key
@@ -52,31 +59,9 @@ module ActiveRecord
52
59
 
53
60
  scope.joins!(join(foreign_table, constraint))
54
61
  end
55
- end
56
-
57
- module Builder
58
- class Association
59
- def self.valid_options(options)
60
- VALID_OPTIONS + [ :primary_type, :strict_primary_type ] + Association.extensions.flat_map(&:valid_options)
61
- end
62
62
  end
63
63
  end
64
-
65
- class BelongsToPolymorphicAssociation < BelongsToAssociation
66
- def klass
67
- type = owner[reflection.foreign_type]
68
- type.presence && type.capitalize.singularize.constantize
69
- end
70
-
71
- private
72
- def replace_keys(record)
73
- super
74
- owner[reflection.foreign_type] = record ? get_type_value(record) : nil
75
- end
76
-
77
- def get_type_value(record)
78
- BetterRecord::PolymorphicOverride.polymorphic_value(record.class, reflection.options)
79
- end
80
- end
81
64
  end
82
65
  end
66
+
67
+ ActiveRecord::Associations::AssociationScope.send(:include, BetterRecord::AssociationsExtensions::AssociationScopeExtensions)
@@ -0,0 +1,29 @@
1
+ require 'active_support/concern'
2
+ require 'active_record/associations'
3
+ require 'active_record/associations/belongs_to_polymorphic_association'
4
+
5
+ module BetterRecord
6
+ module AssociationsExtensions
7
+ module BelongsToPolymorphicAssociationExtensions
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ def klass
12
+ type = owner[reflection.foreign_type]
13
+ type.presence && type.capitalize.singularize.constantize
14
+ end
15
+
16
+ def replace_keys record
17
+ super
18
+ owner[reflection.foreign_type] = record ? get_type_value(record) : nil
19
+ end
20
+
21
+ def get_type_value record
22
+ BetterRecord::PolymorphicOverride.polymorphic_value(record.class, reflection.options)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ ActiveRecord::Associations::BelongsToPolymorphicAssociation.send(:include, BetterRecord::AssociationsExtensions::BelongsToPolymorphicAssociationExtensions)
@@ -0,0 +1,25 @@
1
+ require 'active_support/concern'
2
+ require 'active_record/associations'
3
+ require 'active_record/associations/builder/association'
4
+
5
+ module BetterRecord
6
+ module AssociationsExtensions
7
+ module BuilderExtensions
8
+ module AssociationExtensions
9
+ extend ActiveSupport::Concern
10
+
11
+ included do |k_to_override|
12
+ class << k_to_override
13
+ alias_method :og_valid_options, :valid_options
14
+
15
+ def valid_options(options)
16
+ og_valid_options(options) + [ :primary_type, :strict_primary_type ]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ ActiveRecord::Associations::Builder::Association.send(:include, BetterRecord::AssociationsExtensions::BuilderExtensions::AssociationExtensions)
@@ -0,0 +1,160 @@
1
+ require 'active_support/concern'
2
+ require 'active_record/base'
3
+
4
+ module BetterRecord
5
+ module BaseExtensions
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ before_validation :set_booleans
10
+ end
11
+
12
+ class_methods do
13
+ def table_name_defined?
14
+ @table_name_defined ||= method_defined?(:table_name) || !!table_name.present?
15
+ end
16
+
17
+ def table_name_has_schema?
18
+ @table_name_has_schema ||= (table_name =~ /\w+\.\w+/)
19
+ end
20
+
21
+ def table_name_without_schema
22
+ @table_name_without_schema ||= (table_name =~ /\w+\.\w+/) ? table_name.split('.').last : table_name
23
+ end
24
+
25
+ def table_name_with_schema
26
+ @table_name_without_schema ||= "#{table_schema}.#{table_name_without_schema}"
27
+ end
28
+
29
+ def table_schema
30
+ @table_schema ||= table_name_has_schema? ? table_name.split('.').first : 'public'
31
+ end
32
+
33
+ def audit_relation_name
34
+ @@audit_relation_name ||= (BetterRecord.audit_relation_name.presence || :audits).to_sym
35
+ end
36
+
37
+ def boolean_columns
38
+ []
39
+ end
40
+
41
+ def column_comments(prefix = '')
42
+ longest_name = 0
43
+ column_names.each {|nm| longest_name = nm.length if nm.length > longest_name}
44
+ longest_name += 1
45
+ str = ''
46
+ columns.each do |col|
47
+ unless col.name == 'id'
48
+ spaces = "#{' ' * (longest_name - col.name.length)}"
49
+ is_required = "#{col.null == false ? ', required' : ''}"
50
+ is_default = "#{col.default ? ", default: #{col.default}" : ''}"
51
+ str << "#{prefix}##{spaces}#{col.name}: :#{col.type}#{is_required}\n"
52
+ end
53
+ end
54
+ str
55
+ end
56
+
57
+ def default_print
58
+ column_names
59
+ end
60
+
61
+ def find_or_retry_by(*args)
62
+ found = nil
63
+ retries = 0
64
+ begin
65
+ raise ActiveRecord::RecordNotFound unless found = find_by(*args)
66
+ return found
67
+ rescue
68
+ sleep retries += 1
69
+ retry if (retries) < 5
70
+ end
71
+ found
72
+ end
73
+
74
+ def queue_adapter_inline?
75
+ @@queue_adapter ||= Rails.application.config.active_job.queue_adapter
76
+ @@queue_adapter == :inline
77
+ end
78
+
79
+ def table_size
80
+ BetterRecord::TableSize.unscoped.find_by(name: table_name_without_schema, schema: table_schema)
81
+ end
82
+
83
+ def transaction(*args)
84
+ super(*args) do
85
+ if Current.user
86
+ ip = Current.ip_address ? "'#{Current.ip_address}'" : 'NULL'
87
+
88
+ ActiveRecord::Base.connection.execute <<-SQL
89
+ CREATE TEMP TABLE IF NOT EXISTS
90
+ "_app_user" (user_id integer, user_type text, ip_address inet);
91
+
92
+ UPDATE
93
+ _app_user
94
+ SET
95
+ user_id=#{Current.user.id},
96
+ user_type='#{Current.user.class.to_s}',
97
+ ip_address=#{ip};
98
+
99
+ INSERT INTO
100
+ _app_user (user_id, user_type, ip_address)
101
+ SELECT
102
+ #{Current.user.id},
103
+ '#{Current.user.class.to_s}',
104
+ #{ip}
105
+ WHERE NOT EXISTS (SELECT * FROM _app_user);
106
+ SQL
107
+ end
108
+
109
+ yield
110
+ end
111
+ end
112
+ end
113
+
114
+
115
+ # == Instance Methods =====================================================
116
+ def queue_adapter_inline?
117
+ self.class.queue_adapter_inline?
118
+ end
119
+
120
+ %w(path url).each do |cat|
121
+ self.__send__ :define_method, :"rails_blob_#{cat}" do |*args|
122
+ Rails.application.routes.url_helpers.__send__ :"rails_blob_#{cat}", *args
123
+ end
124
+ end
125
+
126
+ def purge(attached)
127
+ attached.__send__ queue_adapter_inline? ? :purge : :purge_later
128
+ end
129
+
130
+ def boolean_columns
131
+ self.class.boolean_columns
132
+ end
133
+
134
+ def default_print
135
+ self.class.default_print
136
+ end
137
+
138
+ private
139
+ # def table_name_has_schema?
140
+ # self.class.table_name_has_schema?
141
+ # end
142
+ #
143
+ # def table_schema
144
+ # self.class.table_schema
145
+ # end
146
+ #
147
+ # def table_name_without_schema
148
+ # self.class.table_name_without_schema
149
+ # end
150
+
151
+ def set_booleans
152
+ self.class.boolean_columns.each do |nm|
153
+ self.__send__("#{nm}=", __send__("#{nm}=", !!Boolean.parse(__send__ nm)))
154
+ end
155
+ true
156
+ end
157
+ end
158
+ end
159
+
160
+ ActiveRecord::Base.send(:include, BetterRecord::BaseExtensions)
@@ -1,3 +1,5 @@
1
+ require 'active_record/reflection'
2
+
1
3
  module ActiveRecord
2
4
  module Reflection
3
5
  class AbstractReflection
@@ -6,6 +6,7 @@ module BetterRecord
6
6
  begin
7
7
  type_val = klass.__send__(type_method)
8
8
  rescue
9
+ puts type_method, klass, type_val
9
10
  if type_val == :table_name_without_schema
10
11
  type_val = klass.table_name
11
12
  else
@@ -21,7 +22,8 @@ module BetterRecord
21
22
 
22
23
  def self.all_types(klass)
23
24
  keys = [ :polymorphic_name, :table_name ]
24
- key |= [BetterRecord.default_polymorphic_method] if BetterRecord.default_polymorphic_method.present?
25
+ keys |= [BetterRecord.default_polymorphic_method] if BetterRecord.default_polymorphic_method.present?
26
+ p keys
25
27
  values = []
26
28
  keys.each do |k|
27
29
  val = nil
@@ -1,3 +1,3 @@
1
1
  module BetterRecord
2
- VERSION = '0.7.0'
2
+ VERSION = '0.7.1'
3
3
  end
@@ -4,7 +4,7 @@ module BetterRecord
4
4
  # #
5
5
  # default_polymorphic_method: BR_DEFAULT_POLYMORPHIC_METHOD #
6
6
  # db_audit_schema: BR_DB_AUDIT_SCHEMA #
7
- # has_audits_by_default: BR_ADD_HAS_MANY #
7
+ # has_auditing_relation_by_default: BR_ADD_HAS_MANY #
8
8
  # audit_relation_name: BR_AUDIT_RELATION_NAME #
9
9
  # layout_template: BR_LAYOUT_TEMPLATE #
10
10
  # app_domain_name: APP_DOMAIN_NAME #
@@ -23,7 +23,7 @@ module BetterRecord
23
23
  # uncomment the following line to add an association for table audits
24
24
  # directly to ActiveRecord::Base. DEFAULT - false
25
25
 
26
- # self.has_audits_by_default = true
26
+ # self.has_auditing_relation_by_default = true
27
27
 
28
28
  # uncomment the following line to change the association name for
29
29
  # auditing lookups. DEFAULT - :audits
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sampson Crowley
@@ -171,9 +171,8 @@ files:
171
171
  - app/views/better_record/table_sizes/index.html.erb
172
172
  - app/views/better_record/table_sizes/show.html.erb
173
173
  - app/views/layouts/better_record/application.html.erb
174
- - config/initializers/active_record/associations.rb
175
174
  - config/initializers/active_record/money_type.rb
176
- - config/initializers/active_record/reflection.rb
175
+ - config/initializers/concerns.rb
177
176
  - config/initializers/core_ext/boolean.rb
178
177
  - config/initializers/core_ext/date.rb
179
178
  - config/initializers/core_ext/integer.rb
@@ -189,6 +188,11 @@ files:
189
188
  - db/postgres-audit-trigger.psql
190
189
  - lib/better_record.rb
191
190
  - lib/better_record/batches.rb
191
+ - lib/better_record/concerns/active_record_extensions/associations_extensions/association_scope_extensions.rb
192
+ - lib/better_record/concerns/active_record_extensions/associations_extensions/belongs_to_polymorphic_extensions.rb
193
+ - lib/better_record/concerns/active_record_extensions/associations_extensions/builder_extensions/association_extensions.rb
194
+ - lib/better_record/concerns/active_record_extensions/base_extensions.rb
195
+ - lib/better_record/concerns/active_record_extensions/reflection_extensions.rb
192
196
  - lib/better_record/engine.rb
193
197
  - lib/better_record/fake_redis.rb
194
198
  - lib/better_record/migration.rb