active_record-framing 0.1.0.pre.3 → 0.1.0.pre.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bb54c09be5bd01b84d55f0bb8e959e5ef1a5c7f6a13d4f6ed55089f901129b1
4
- data.tar.gz: 20d17ac8e31e7866148b70d2983d2941bd298e4cd9fa6e94e5756e85a52a904d
3
+ metadata.gz: f02f550ffc7f48015697d04cdc5ad1a54a3693c4c0fcb141500224fc78cfeec7
4
+ data.tar.gz: 96ef5227beb750c1e6845ecaafd7d11b5dc888f31a96acf29c2a26dde37d544e
5
5
  SHA512:
6
- metadata.gz: 8ba3bbbb8ebc8eeaabdbcabc927ed2a2358922c91286f99007a99354e38165f6f62a33c56030b2e3cf1e3457864793feed1a9277c1eacd4f52dbf55d1cf76463
7
- data.tar.gz: 6dbd8f819768e3e90ce8b9777d7280fa793cbe276a9af84da4fed7ab961b4fba1cc284e7cdb337c07372c8d623d4b2c0db43f5cdc3854b74e379da0a5de85db1
6
+ metadata.gz: e73a79efe0958a13aaf6845cd0ee546bd8dcc7520cbc062f91aa1d7dab36ecd707f1c0f4f454f1b3027369ea1ac74f61112a2167b9507204861478981474785e
7
+ data.tar.gz: b90c1d6ea6bba1888cc6a19693682409ea553415073ae14c23db7431855d596b86b0cbb1c8edc81e9f9bfa1032d0b6c0545fbd2b056d09408aa36d2c27840fe6
@@ -147,21 +147,24 @@ module ActiveRecord
147
147
  the_frame = body.respond_to?(:to_proc) ? body : body.method(:call)
148
148
  cte_relation = relation.merge!(relation.instance_exec(&the_frame) || relation)
149
149
 
150
- # self.const_set constant, Class.new(DelegateClass(self)) do |klass|
151
150
  delegator = self.name.to_sym
152
- self.const_set(constant, self.dup).class_eval do |klass|
153
- # self.const_set constant, Class.new do |klass|
154
- extend SingleForwardable
155
- def_delegators delegator, :type_caster, :table_name, :discriminate_class_for_record
151
+ new_class = self.const_set constant, (Class.new(self) do |klass|
152
+ klass.abstract_class = true
153
+ klass.table_name = superclass.table_name
154
+
155
+ def klass.discriminate_class_for_record(record)
156
+ superclass.send(:discriminate_class_for_record, record)
157
+ end
156
158
 
157
159
  klass.default_frames = []
158
160
 
159
- @arel_table = klass.arel_table.dup.tap do |at|
161
+ @arel_table = superclass.arel_table.dup.tap do |at|
160
162
  at.name = arel_tn
161
163
  end
162
164
 
163
- klass.current_frame = build_frame(cte_relation, &block)
164
- end
165
+ end)
166
+
167
+ new_class.current_frame = new_class.build_frame(cte_relation, &block)
165
168
 
166
169
  if dangerous_class_const?(constant)
167
170
  raise ArgumentError, "You tried to define a frame named \"#{constant}\" " \
@@ -3,29 +3,44 @@ module ActiveRecord
3
3
  module QueryMethods
4
4
 
5
5
  if ::ActiveRecord.version >= Gem::Version.new("5.1") # 5.1+
6
- def frames_values
7
- get_value(:frames)
6
+ {
7
+ frames: ::ActiveRecord::Relation::FROZEN_EMPTY_HASH,
8
+ reframe: ::ActiveRecord::Relation::FROZEN_EMPTY_HASH
9
+ }.each do |value_name, default_value|
10
+ define_method("#{value_name}_values") do
11
+ get_value(value_name)
12
+ end
13
+ define_method("#{value_name}_values=") do |value|
14
+ set_value(value_name, value)
15
+ end
16
+ ::ActiveRecord::Relation::DEFAULT_VALUES[value_name] = default_value
8
17
  end
9
- def frames_values=(value)
10
- set_value(:frames, value)
11
- end
12
- ::ActiveRecord::Relation::DEFAULT_VALUES[:frames] = ::ActiveRecord::Relation::FROZEN_EMPTY_HASH
13
18
  elsif ::ActiveRecord.version >= Gem::Version.new("5.0") # 5.0+
14
- def frames_values
15
- @values[:frames] || ::ActiveRecord::Relation::FROZEN_EMPTY_HASH
16
- end
17
- def frames_values=(values)
18
- assert_mutability!
19
- @values[:frames] = values
19
+ {
20
+ frames: ::ActiveRecord::Relation::FROZEN_EMPTY_HASH,
21
+ reframe: ::ActiveRecord::Relation::FROZEN_EMPTY_HASH
22
+ }.each do |value_name, default_value|
23
+ define_method("#{value_name}_values") do
24
+ @values[value_name] || default_value
25
+ end
26
+ define_method("#{value_name}_values=") do |values|
27
+ assert_mutability!
28
+ @values[value_name] = values
29
+ end
20
30
  end
21
31
  elsif ::ActiveRecord.version >= Gem::Version.new("4.2") # 4.2+
22
- def frames_values
23
- @values[:frames] || {}
24
- end
25
- def frames_values=(values)
26
- raise ImmutableRelation if @loaded
27
- check_cached_relation
28
- @values[:frames] = values
32
+ {
33
+ frames: {},
34
+ reframe: {}
35
+ }.each do |value_name, default_value|
36
+ define_method("#{value_name}_values") do
37
+ @values[value_name] || default_value
38
+ end
39
+ define_method("#{value_name}_values=") do |values|
40
+ raise ImmutableRelation if @loaded
41
+ check_cached_relation
42
+ @values[value_name] = values
43
+ end
29
44
  end
30
45
  else
31
46
  raise NotImplementedError, "ActiveRecord::Framing does not support Rails #{::ActiveRecord.version}"
@@ -48,72 +63,13 @@ module ActiveRecord
48
63
  self
49
64
  end
50
65
 
51
- # Removes an unwanted relation that is already defined on a chain of relations.
52
- # This is useful when passing around chains of relations and would like to
53
- # modify the relations without reconstructing the entire chain.
54
- #
55
- # User.order('email DESC').unframe(:order) == User.all
56
- #
57
- # The method arguments are symbols which correspond to the names of the methods
58
- # which should be unframed. The valid arguments are given in VALID_UNSCOPING_VALUES.
59
- # The method can also be called with multiple arguments. For example:
60
- #
61
- # User.order('email DESC').select('id').where(name: "John")
62
- # .unframe(:order, :select, :where) == User.all
63
- #
64
- # One can additionally pass a hash as an argument to unframe specific +:where+ values.
65
- # This is done by passing a hash with a single key-value pair. The key should be
66
- # +:where+ and the value should be the where value to unframe. For example:
67
- #
68
- # User.where(name: "John", active: true).unframe(where: :name)
69
- # == User.where(active: true)
70
- #
71
- # This method is similar to #except, but unlike
72
- # #except, it persists across merges:
73
- #
74
- # User.order('email').merge(User.except(:order))
75
- # == User.order('email')
76
- #
77
- # User.order('email').merge(User.unframe(:order))
78
- # == User.all
79
- #
80
- # This means it can be used in association definitions:
81
- #
82
- # has_many :comments, -> { unframe(where: :trashed) }
83
- #
84
- # def unframe(*args)
85
- # check_if_method_has_arguments!(:unframe, args)
86
- # spawn.unframe!(*args)
87
- # end
88
-
89
- # def unframe!(*args) # :nodoc:
90
- # args.flatten!
91
- # self.unframe_values += args
92
-
93
- # args.each do |frame|
94
- # case frame
95
- # when Symbol
96
- # frame = :left_outer_joins if frame == :left_joins
97
- # if !VALID_UNSCOPING_VALUES.include?(frame)
98
- # raise ArgumentError, "Called unframe() with invalid unframing argument ':#{frame}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}."
99
- # end
100
- # set_value(frame, DEFAULT_VALUES[frame])
101
- # when Hash
102
- # frame.each do |key, target_value|
103
- # if key != :where
104
- # raise ArgumentError, "Hash arguments in .unframe(*args) must have :where as the key."
105
- # end
106
-
107
- # target_values = Array(target_value).map(&:to_s)
108
- # self.where_clause = where_clause.except(*target_values)
109
- # end
110
- # else
111
- # raise ArgumentError, "Unrecognized framing: #{args.inspect}. Use .unframe(where: :attribute_name) or .unframe(:order), for example."
112
- # end
113
- # end
114
-
115
- # self
116
- # end
66
+ def reframe(*args)
67
+ args.flatten!
68
+ # TODO: Convert array (if present) to nil hash {value => nil}
69
+ # and merge with hash (if present) as second arg
70
+ self.reframe_values = self.reframe_values.merge(args.first)
71
+ self
72
+ end
117
73
  end
118
74
  end
119
75
  end
@@ -6,11 +6,6 @@ module ActiveRecord
6
6
  def build_arel(*)
7
7
  super.tap do |ar|
8
8
  unless ignore_default_frame?
9
- # alias_tracker.aliased_table_for(
10
- # reflection.table_name,
11
- # table_alias_for(reflection, parent, reflection != node.reflection),
12
- # reflection.klass.type_caster
13
- # )
14
9
  build_frames(ar)
15
10
  ar.with(*frames_values.values) if frames_values.any?
16
11
  end
@@ -34,14 +29,32 @@ module ActiveRecord
34
29
  # @table_alias=nil>,
35
30
  # NOTE: In Rails 5.2 (at least) we could use the InnerJoin.left.type_caster
36
31
  def build_frames(manager)
37
- join_names = manager.join_sources.collect do |source|
38
- source.left.name.to_s # TODO: Need to_s?
32
+ # NOTE: We cannot early exclude associations because some associations are different from their table names
33
+ # TODO: cache known associations?
34
+ assocs = klass.reflect_on_all_associations.inject(Hash.new) do |assocs, assoc|
35
+ begin
36
+ assocs[assoc.table_name] = assoc
37
+ rescue NameError => e
38
+ # warn <<~WARN.chomp
39
+ # ActiveRecord::Framing was trying to inspect the association #{assoc.name}
40
+ # on the #{assoc.active_record.name} model but seems there is an issue
41
+ # locating the model backing it.
42
+ # WARN
43
+ end
44
+ assocs
39
45
  end
40
46
 
41
- # NOTE: We cannot early exclude associations because some associations are different from their table names
42
- klass.reflect_on_all_associations.each do |assoc|
43
- if join_names.include?(assoc.table_name) && assoc.klass.default_frames.any? && assoc_default_frame = assoc.klass.send(:build_default_frame)
44
- merge!(assoc_default_frame)
47
+ manager.join_sources.each do |join_source|
48
+ next unless join_source&.left&.respond_to?(:name)
49
+ if assoc = assocs[join_source.left.name]
50
+ source = reframe_values.fetch(assoc.name) { assoc.klass }
51
+
52
+ join_source.left.name = source.arel_table.name
53
+ if source < ::ActiveRecord::Base
54
+ merge!(source.all)
55
+ elsif source < ::ActiveRecord::Relation
56
+ merge!(source)
57
+ end
45
58
  end
46
59
  end
47
60
  end
@@ -59,42 +72,6 @@ module ActiveRecord
59
72
  end
60
73
  end
61
74
 
62
- # def reframe(*args) # :nodoc:
63
- # args.compact!
64
- # args.flatten!
65
- # # binding.pry
66
- # self
67
- # end
68
-
69
- # def reframe!(*args) # :nodoc:
70
- # args.flatten!
71
- # self.unframe_values += args
72
-
73
- # args.each do |frame|
74
- # case frame
75
- # when Symbol
76
- # frame = :left_outer_joins if frame == :left_joins
77
- # if !VALID_UNSCOPING_VALUES.include?(frame)
78
- # raise ArgumentError, "Called unframe() with invalid unframing argument ':#{frame}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}."
79
- # end
80
- # set_value(frame, DEFAULT_VALUES[frame])
81
- # when Hash
82
- # frame.each do |key, target_value|
83
- # if key != :where
84
- # raise ArgumentError, "Hash arguments in .unframe(*args) must have :where as the key."
85
- # end
86
-
87
- # target_values = Array(target_value).map(&:to_s)
88
- # self.where_clause = where_clause.except(*target_values)
89
- # end
90
- # else
91
- # raise ArgumentError, "Unrecognized framing: #{args.inspect}. Use .unframe(where: :attribute_name) or .unframe(:order), for example."
92
- # end
93
- # end
94
-
95
- # self
96
- # end
97
-
98
75
  # Frame all queries to the current frame.
99
76
  #
100
77
  # Comment.where(post_id: 1).framing do
@@ -116,22 +93,6 @@ module ActiveRecord
116
93
  def scoping
117
94
  framing { super }
118
95
  end
119
-
120
- # def _exec_frame(*args, &block) # :nodoc:
121
- # @delegate_to_klass = true
122
- # instance_exec(*args, &block) || self
123
- # ensure
124
- # @delegate_to_klass = false
125
- # end
126
-
127
- # def frame_for_create
128
- # where_values_hash.merge!(create_with_value.stringify_keys)
129
- # end
130
-
131
- # def empty_frame? # :nodoc:
132
- # @values == klass.unframed.values
133
- # end
134
-
135
96
  end
136
97
  end
137
98
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Framing
3
- VERSION = "0.1.0-3"
3
+ VERSION = "0.1.0-4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record-framing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.3
4
+ version: 0.1.0.pre.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Stevens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-09 00:00:00.000000000 Z
11
+ date: 2019-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord