Class: Graphiti::ResourceProxy
- Includes:
- Enumerable
- Defined in:
- lib/graphiti/resource_proxy.rb
Instance Attribute Summary collapse
-
#cache ⇒ Object
readonly
Returns the value of attribute cache.
-
#cache_expires_in ⇒ Object
readonly
Returns the value of attribute cache_expires_in.
-
#cache_tag ⇒ Object
readonly
Returns the value of attribute cache_tag.
-
#payload ⇒ Object
readonly
Returns the value of attribute payload.
-
#query ⇒ Object
readonly
Returns the value of attribute query.
-
#resource ⇒ Object
readonly
Returns the value of attribute resource.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
Instance Method Summary collapse
- #[](val) ⇒ Object
- #as_graphql(options = {}) ⇒ Object
- #as_json(options = {}) ⇒ Object
-
#assign_attributes(params) ⇒ Object
Apply request params to the underlying model without saving it, Rails-style: the params are always passed explicitly, in the same request-params shape find/build accept.
- #cache? ⇒ Boolean (also: #cached?)
- #cache_key ⇒ Object
- #cache_key_with_version ⇒ Object
- #data ⇒ Object (also: #to_a, #resolve_data)
-
#data=(models) ⇒ Object
Records supplied directly, no scope resolution.
- #debug_requested? ⇒ Boolean
- #destroy ⇒ Object
- #each(&blk) ⇒ Object
- #errors ⇒ Object
- #etag ⇒ Object
- #extra_fields ⇒ Object
- #fields ⇒ Object
- #future_resolve_data ⇒ Object
- #include_hash ⇒ Object
-
#initialize(resource, scope, query, payload: nil, single: false, raise_on_missing: false, assign_action: nil, cache: nil, cache_expires_in: nil, cache_tag: nil) ⇒ ResourceProxy
constructor
A new instance of ResourceProxy.
- #jsonapi_render_options(opts = {}) ⇒ Object
- #meta ⇒ Object
- #pagination ⇒ Object
- #raise_on_missing? ⇒ Boolean
- #resource_cache_tag ⇒ Object
- #save(action: :create) ⇒ Object
- #single? ⇒ Boolean
- #stats ⇒ Object
- #to_graphql(options = {}) ⇒ Object
- #to_json(options = {}) ⇒ Object
- #to_jsonapi(options = {}) ⇒ Object
- #to_xml(options = {}) ⇒ Object
-
#update(params = nil) ⇒ Object
(also: #update_attributes)
Rails-style: pass params to assign and save in one call, or call with no arguments to save a payload assigned earlier (via find or #assign_attributes).
- #updated_at ⇒ Object
Constructor Details
#initialize(resource, scope, query, payload: nil, single: false, raise_on_missing: false, assign_action: nil, cache: nil, cache_expires_in: nil, cache_tag: nil) ⇒ ResourceProxy
Returns a new instance of ResourceProxy.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/graphiti/resource_proxy.rb', line 7 def initialize( resource, scope, query, payload: nil, single: false, raise_on_missing: false, assign_action: nil, cache: nil, cache_expires_in: nil, cache_tag: nil ) @resource = resource @scope = scope @query = query @payload = payload @single = single @raise_on_missing = raise_on_missing @assign_action = assign_action @cache = cache @cache_expires_in = cache_expires_in @cache_tag = cache_tag end |
Instance Attribute Details
#cache ⇒ Object (readonly)
Returns the value of attribute cache.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def cache @cache end |
#cache_expires_in ⇒ Object (readonly)
Returns the value of attribute cache_expires_in.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def cache_expires_in @cache_expires_in end |
#cache_tag ⇒ Object (readonly)
Returns the value of attribute cache_tag.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def cache_tag @cache_tag end |
#payload ⇒ Object (readonly)
Returns the value of attribute payload.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def payload @payload end |
#query ⇒ Object (readonly)
Returns the value of attribute query.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def query @query end |
#resource ⇒ Object (readonly)
Returns the value of attribute resource.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def resource @resource end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
5 6 7 |
# File 'lib/graphiti/resource_proxy.rb', line 5 def scope @scope end |
Instance Method Details
#[](val) ⇒ Object
50 51 52 |
# File 'lib/graphiti/resource_proxy.rb', line 50 def [](val) data[val] end |
#as_graphql(options = {}) ⇒ Object
81 82 83 |
# File 'lib/graphiti/resource_proxy.rb', line 81 def as_graphql( = {}) Renderer.new(self, ).as_graphql end |
#as_json(options = {}) ⇒ Object
69 70 71 |
# File 'lib/graphiti/resource_proxy.rb', line 69 def as_json( = {}) Renderer.new(self, ).as_json end |
#assign_attributes(params) ⇒ Object
Apply request params to the underlying model without saving it, Rails-style: the params are always passed explicitly, in the same request-params shape find/build accept. They are validated, deserialized, and become the payload #save will persist.
Idempotent per params - calling again with params that normalize to the same payload is a no-op, so the attributes callbacks fire once. Different params re-assign onto the same model instance.
Note the attributes callbacks fire here, outside any transaction opened during #save - the persistence hooks wrap only the save phase, receiving this assigned model.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/graphiti/resource_proxy.rb', line 158 def assign_attributes(params) action = @assign_action || :update params = normalized_params_copy(params) add_endpoint_filter(params, action) validator = ::Graphiti::RequestValidator.new(@resource, params, action) validator.validate! if @assigned_model && same_write_payload?(validator.deserialized_payload) return @assigned_model end @payload = validator.deserialized_payload @assigned_model = @data = @resource.assign_with_relationships( @payload.(action: action), @payload.attributes, @payload.relationships, model_instance: @assigned_model || (data if action == :update) ) end |
#cache? ⇒ Boolean Also known as: cached?
32 33 34 |
# File 'lib/graphiti/resource_proxy.rb', line 32 def cache? !!@cache end |
#cache_key ⇒ Object
276 277 278 279 280 281 282 283 284 |
# File 'lib/graphiti/resource_proxy.rb', line 276 def cache_key ActiveSupport::Cache.( [ @scope.cache_key, @query.cache_key, resource_cache_tag ].compact_blank ) end |
#cache_key_with_version ⇒ Object
286 287 288 289 290 291 292 293 294 |
# File 'lib/graphiti/resource_proxy.rb', line 286 def cache_key_with_version ActiveSupport::Cache.( [ @scope.cache_key_with_version, @query.cache_key, resource_cache_tag ].compact_blank ) end |
#data ⇒ Object Also known as: to_a, resolve_data
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/graphiti/resource_proxy.rb', line 91 def data return @data unless @data.nil? return assign_attributes(@payload.params) if @assign_action @data = begin records = @scope.resolve raise Graphiti::Errors::RecordNotFound if records.empty? && raise_on_missing? records = records[0] if single? records end end |
#data=(models) ⇒ Object
Records supplied directly, no scope resolution
86 87 88 89 |
# File 'lib/graphiti/resource_proxy.rb', line 86 def data=(models) @data = models [@data].flatten.compact.each { |record| @resource.decorate_record(record) } end |
#debug_requested? ⇒ Boolean
258 259 260 |
# File 'lib/graphiti/resource_proxy.rb', line 258 def debug_requested? query.debug_requested? end |
#destroy ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/graphiti/resource_proxy.rb', line 214 def destroy resolve_data transaction_response = @resource.transaction do = {method: :destroy} model = @resource.destroy(@query.filters[:id], ) model.instance_variable_set(:@__serializer_klass, @resource.serializer) @resource.after_graph_persist(model, ) validator = ::Graphiti::Util::ValidationResponse.new \ model, @payload validator.validate! @resource.before_commit(model, ) {result: validator} end @data, success = transaction_response[:result].to_a success end |
#each(&blk) ⇒ Object
120 121 122 |
# File 'lib/graphiti/resource_proxy.rb', line 120 def each(&blk) to_a.each(&blk) end |
#errors ⇒ Object
46 47 48 |
# File 'lib/graphiti/resource_proxy.rb', line 46 def errors data.errors end |
#etag ⇒ Object
266 267 268 |
# File 'lib/graphiti/resource_proxy.rb', line 266 def etag "W/#{ActiveSupport::Digest.hexdigest(cache_key_with_version.to_s)}" end |
#extra_fields ⇒ Object
254 255 256 |
# File 'lib/graphiti/resource_proxy.rb', line 254 def extra_fields query.extra_fields end |
#fields ⇒ Object
250 251 252 |
# File 'lib/graphiti/resource_proxy.rb', line 250 def fields query.fields end |
#future_resolve_data ⇒ Object
107 108 109 110 111 112 113 114 |
# File 'lib/graphiti/resource_proxy.rb', line 107 def future_resolve_data @scope.future_resolve.then do |records| raise Graphiti::Errors::RecordNotFound if records.empty? && raise_on_missing? records = records[0] if single? @data = records end end |
#include_hash ⇒ Object
243 244 245 246 247 248 |
# File 'lib/graphiti/resource_proxy.rb', line 243 def include_hash @include_hash ||= begin base = @payload ? @payload.include_hash : {} base.deep_merge(@query.include_hash) end end |
#jsonapi_render_options(opts = {}) ⇒ Object
54 55 56 57 58 |
# File 'lib/graphiti/resource_proxy.rb', line 54 def (opts = {}) opts[:expose] ||= {} opts[:expose][:context] = Graphiti.context[:object] opts end |
#meta ⇒ Object
116 117 118 |
# File 'lib/graphiti/resource_proxy.rb', line 116 def @meta ||= data.respond_to?(:meta) ? data. : {} end |
#pagination ⇒ Object
142 143 144 |
# File 'lib/graphiti/resource_proxy.rb', line 142 def pagination @pagination ||= Delegates::Pagination.new(self) end |
#raise_on_missing? ⇒ Boolean
42 43 44 |
# File 'lib/graphiti/resource_proxy.rb', line 42 def raise_on_missing? !!@raise_on_missing end |
#resource_cache_tag ⇒ Object
270 271 272 273 274 |
# File 'lib/graphiti/resource_proxy.rb', line 270 def resource_cache_tag return unless @cache_tag.present? && @resource.respond_to?(@cache_tag) @resource.try(@cache_tag) end |
#save(action: :create) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/graphiti/resource_proxy.rb', line 178 def save(action: :create) # TODO: remove this. Only used for persisting many-to-many with AR # (see activerecord adapter) original = Graphiti.context[:namespace] begin Graphiti.context[:namespace] = action # An assigned model can only come from #assign_attributes, which # validated the payload it stored - re-validating here would run the # writable guards (and their guard_model lookups) a redundant time. unless @assigned_model ::Graphiti::RequestValidator.new(@resource, @payload.params, action).validate! end validator = persist { @resource.persist_with_relationships \ @payload.(action: action), @payload.attributes, @payload.relationships, assigned_model: @assigned_model } ensure Graphiti.context[:namespace] = original end @data, success = validator.to_a if success # If the context namespace is `update` or `create`, certain # adapters will cause N+1 validation calls, so lets explicitly # switch to a lookup context. Graphiti.with_context(Graphiti.context[:object], :show) do @scope.resolve_sideloads([@data]) end end success end |
#single? ⇒ Boolean
38 39 40 |
# File 'lib/graphiti/resource_proxy.rb', line 38 def single? !!@single end |
#stats ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/graphiti/resource_proxy.rb', line 124 def stats @stats ||= if @query.hash[:stats] scope = @scope.unpaginated_object if resource.adapter.can_group? if (group = @query.hash[:stats].delete(:group_by)) scope = resource.adapter.group(scope, group[0]) end end payload = Stats::Payload.new @resource, @query, scope, data payload.generate else {} end end |
#to_graphql(options = {}) ⇒ Object
77 78 79 |
# File 'lib/graphiti/resource_proxy.rb', line 77 def to_graphql( = {}) Renderer.new(self, ).to_graphql end |
#to_json(options = {}) ⇒ Object
65 66 67 |
# File 'lib/graphiti/resource_proxy.rb', line 65 def to_json( = {}) Renderer.new(self, ).to_json end |
#to_jsonapi(options = {}) ⇒ Object
60 61 62 63 |
# File 'lib/graphiti/resource_proxy.rb', line 60 def to_jsonapi( = {}) = () Renderer.new(self, ).to_jsonapi end |
#to_xml(options = {}) ⇒ Object
73 74 75 |
# File 'lib/graphiti/resource_proxy.rb', line 73 def to_xml( = {}) Renderer.new(self, ).to_xml end |
#update(params = nil) ⇒ Object Also known as: update_attributes
Rails-style: pass params to assign and save in one call, or call with no arguments to save a payload assigned earlier (via find or #assign_attributes).
235 236 237 238 239 |
# File 'lib/graphiti/resource_proxy.rb', line 235 def update(params = nil) assign_attributes(params) if params resolve_data save(action: :update) end |
#updated_at ⇒ Object
262 263 264 |
# File 'lib/graphiti/resource_proxy.rb', line 262 def updated_at @scope.updated_at end |