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 |
# 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
49 50 51 |
# File 'lib/graphiti/resource_proxy.rb', line 49 def [](val) data[val] end |
#as_graphql(options = {}) ⇒ Object
80 81 82 |
# File 'lib/graphiti/resource_proxy.rb', line 80 def as_graphql( = {}) Renderer.new(self, ).as_graphql end |
#as_json(options = {}) ⇒ Object
68 69 70 |
# File 'lib/graphiti/resource_proxy.rb', line 68 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.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/graphiti/resource_proxy.rb', line 157 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?
31 32 33 |
# File 'lib/graphiti/resource_proxy.rb', line 31 def cache? !!@cache end |
#cache_key ⇒ Object
275 276 277 278 279 280 281 282 283 |
# File 'lib/graphiti/resource_proxy.rb', line 275 def cache_key ActiveSupport::Cache.( [ @scope.cache_key, @query.cache_key, resource_cache_tag ].compact_blank ) end |
#cache_key_with_version ⇒ Object
285 286 287 288 289 290 291 292 293 |
# File 'lib/graphiti/resource_proxy.rb', line 285 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
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/graphiti/resource_proxy.rb', line 90 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
85 86 87 88 |
# File 'lib/graphiti/resource_proxy.rb', line 85 def data=(models) @data = models [@data].flatten.compact.each { |record| @resource.decorate_record(record) } end |
#debug_requested? ⇒ Boolean
257 258 259 |
# File 'lib/graphiti/resource_proxy.rb', line 257 def debug_requested? query.debug_requested? end |
#destroy ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/graphiti/resource_proxy.rb', line 213 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
119 120 121 |
# File 'lib/graphiti/resource_proxy.rb', line 119 def each(&blk) to_a.each(&blk) end |
#errors ⇒ Object
45 46 47 |
# File 'lib/graphiti/resource_proxy.rb', line 45 def errors data.errors end |
#etag ⇒ Object
265 266 267 |
# File 'lib/graphiti/resource_proxy.rb', line 265 def etag "W/#{ActiveSupport::Digest.hexdigest(cache_key_with_version.to_s)}" end |
#extra_fields ⇒ Object
253 254 255 |
# File 'lib/graphiti/resource_proxy.rb', line 253 def extra_fields query.extra_fields end |
#fields ⇒ Object
249 250 251 |
# File 'lib/graphiti/resource_proxy.rb', line 249 def fields query.fields end |
#future_resolve_data ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'lib/graphiti/resource_proxy.rb', line 106 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
242 243 244 245 246 247 |
# File 'lib/graphiti/resource_proxy.rb', line 242 def include_hash @include_hash ||= begin base = @payload ? @payload.include_hash : {} base.deep_merge(@query.include_hash) end end |
#jsonapi_render_options(opts = {}) ⇒ Object
53 54 55 56 57 |
# File 'lib/graphiti/resource_proxy.rb', line 53 def (opts = {}) opts[:expose] ||= {} opts[:expose][:context] = Graphiti.context[:object] opts end |
#meta ⇒ Object
115 116 117 |
# File 'lib/graphiti/resource_proxy.rb', line 115 def @meta ||= data.respond_to?(:meta) ? data. : {} end |
#pagination ⇒ Object
141 142 143 |
# File 'lib/graphiti/resource_proxy.rb', line 141 def pagination @pagination ||= Delegates::Pagination.new(self) end |
#raise_on_missing? ⇒ Boolean
41 42 43 |
# File 'lib/graphiti/resource_proxy.rb', line 41 def raise_on_missing? !!@raise_on_missing end |
#resource_cache_tag ⇒ Object
269 270 271 272 273 |
# File 'lib/graphiti/resource_proxy.rb', line 269 def resource_cache_tag return unless @cache_tag.present? && @resource.respond_to?(@cache_tag) @resource.try(@cache_tag) end |
#save(action: :create) ⇒ Object
177 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 |
# File 'lib/graphiti/resource_proxy.rb', line 177 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
37 38 39 |
# File 'lib/graphiti/resource_proxy.rb', line 37 def single? !!@single end |
#stats ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/graphiti/resource_proxy.rb', line 123 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
76 77 78 |
# File 'lib/graphiti/resource_proxy.rb', line 76 def to_graphql( = {}) Renderer.new(self, ).to_graphql end |
#to_json(options = {}) ⇒ Object
64 65 66 |
# File 'lib/graphiti/resource_proxy.rb', line 64 def to_json( = {}) Renderer.new(self, ).to_json end |
#to_jsonapi(options = {}) ⇒ Object
59 60 61 62 |
# File 'lib/graphiti/resource_proxy.rb', line 59 def to_jsonapi( = {}) = () Renderer.new(self, ).to_jsonapi end |
#to_xml(options = {}) ⇒ Object
72 73 74 |
# File 'lib/graphiti/resource_proxy.rb', line 72 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).
234 235 236 237 238 |
# File 'lib/graphiti/resource_proxy.rb', line 234 def update(params = nil) assign_attributes(params) if params resolve_data save(action: :update) end |
#updated_at ⇒ Object
261 262 263 |
# File 'lib/graphiti/resource_proxy.rb', line 261 def updated_at @scope.updated_at end |