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

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: 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