module Pakyow::Reflection::Extension::Controller
Public Instance Methods
perform_reflected_action()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 122 def perform_reflected_action with_reflected_action do |reflected_action| logger.debug { "[reflection] performing `#{[self.class.name_of_self, connection.values[:__endpoint_name]].join("_")}' for `#{reflected_action.view_path}'" } proxy = data.public_send(reflected_action.scope.plural_name) # Pull initial values from the params. # values = params[reflected_action.scope.name] # Associate the object with its parent when creating. # if self.class.parent && connection.get(:__endpoint_name) == :create # TODO: Handle cases where objects are associated by id but routed by another field. # Implement when we allow foreign keys to be specified in associations. # if proxy.source.class.attributes.key?(self.class.parent.nested_param) values[self.class.parent.nested_param] = params[self.class.parent.nested_param] end end # Limit the action for update, delete. # if connection.get(:__endpoint_name) == :update || connection.get(:__endpoint_name) == :delete proxy = proxy.public_send(:"by_#{proxy.source.class.primary_key_field}", params[self.class.param]) trigger 404 if proxy.count == 0 end proxy.transaction do unless connection.get(:__endpoint_name) == :delete handle_nested_values_for_source(values, proxy.source.class) end @object = proxy.send( connection.get(:__endpoint_name), values ) end logger.debug { "[reflection] changes have been saved to the `#{proxy.source.class.plural_name}' data source" } end rescue Data::ConstraintViolation trigger 404 end
redirect_to_reflected_destination()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 170 def redirect_to_reflected_destination if destination = reflected_destination logger.debug { "[reflection] redirecting to `#{destination}'" } redirect destination end end
reflected_destination()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 180 def reflected_destination with_reflected_action do |reflected_action| if connection.form && origin = connection.form[:origin] if instance_variable_defined?(:@object) if route = self.class.routes[:get].find { |route| route.name == :show } route.build_path(self.class.path_to_self, **params.merge(@object.one.to_h)) elsif route = self.class.routes[:get].find { |route| route.name == :list } route.build_path(self.class.path_to_self, **params) else origin end else origin end else nil end end end
reflective_expose()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 31 def reflective_expose reflected_endpoint.exposures.each do |reflected_exposure| if reflected_exposure.parent.nil? || reflected_exposure.binding.to_s.include?("form") if dataset = reflected_exposure.dataset query = data.send(reflected_exposure.scope.plural_name) if dataset.include?(:limit) query = query.limit(dataset[:limit].to_i) end if dataset.include?(:order) query = query.order(*dataset[:order].to_a) end if dataset.include?(:query) && dataset[:query] != "all" case dataset[:query] when Array dataset[:query].each do |key, value| value = if respond_to?(value) public_send(value) else value end query = query.public_send(key, value) end else query = query.public_send(dataset[:query].to_s) end end else query = data.send(reflected_exposure.scope.plural_name) if reflects_specific_object?(reflected_exposure.scope.plural_name) if resource = resource_with_name(reflected_exposure.scope.plural_name) if resource == self.class query_param = resource.param params_param = resource.param else query_param = resource.param params_param = resource.nested_param end query = query.send(:"by_#{query_param}", params[params_param]) end end end query = apply_includes_to_query(query, reflected_exposure.scope.plural_name, reflected_exposure.children) if reflects_specific_object?(reflected_exposure.scope.plural_name) && query.count == 0 trigger 404 else if !reflected_exposure.binding.to_s.include?("form") || reflected_endpoint.view_path.end_with?("/edit") logger.debug { "[reflection] exposing dataset for `#{reflected_exposure.binding}': #{query.inspect}" } expose reflected_exposure.binding.to_s, query end end end end end
verify_reflected_form()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 96 def verify_reflected_form with_reflected_action do |reflected_action| local = self verify do required reflected_action.scope.name do reflected_action.attributes.each do |attribute| if attribute.required? required attribute.name do validate :presence end else optional attribute.name end end local.__send__(:verify_nested_data, reflected_action.nested, self) end end logger.debug { "[reflection] verified and validated submitted values for `#{reflected_action.scope.name}'" } end end
with_reflected_action() { |reflected_action| ... }
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 15 def with_reflected_action if reflected_action yield reflected_action else trigger 404 end end
with_reflected_endpoint() { |reflected_endpoint| ... }
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 23 def with_reflected_endpoint if reflected_endpoint yield reflected_endpoint else trigger 404 end end
Private Instance Methods
apply_includes_to_query(query, plural_name, children)
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 289 def apply_includes_to_query(query, plural_name, children) associations = data.send( plural_name ).source.class.associations.values.flatten children.group_by { |child| child.scope.plural_name }.each do |nested_plural_name, child_exposures| association = associations.find { |possible_association| possible_association.associated_source_name == nested_plural_name } if association context = self query = query.including(association.name) { context.__send__(:apply_includes_to_query, self, nested_plural_name, child_exposures.flat_map(&:children)) } end end query end
handle_nested_values_for_source(values, source)
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 253 def handle_nested_values_for_source(values, source) source.associations.values_at(:has_one, :has_many).flatten.each do |association| Array.ensure(values).each do |object| if object.include?(association.name) handle_nested_values_for_source( object[association.name], association.associated_source ) if association.result_type == :many object[association.name] = Array.ensure(object[association.name]).map { |related| if related.include?(association.associated_source.primary_key_field) data.public_send(association.associated_source_name).send( :"by_#{association.associated_source.primary_key_field}", related[association.associated_source.primary_key_field] ).update(related).one else data.public_send(association.associated_source_name).create(related).one end } else related = object[association.name] object[association.name] = if related.include?(association.associated_source.primary_key_field) data.public_send(association.associated_source_name).send( :"by_#{association.associated_source.primary_key_field}", related[association.associated_source.primary_key_field] ).update(related).one else data.public_send(association.associated_source_name).create(related).one end end end end end end
parent_resource_named?(object_name, context = self.class)
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 218 def parent_resource_named?(object_name, context = self.class) if context && context.parent context.parent.__object_name&.name == object_name || parent_resource_named?(object_name, context.parent) else false end end
reflected_action()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 202 def reflected_action connection.get(:__reflected_action) end
reflected_endpoint()
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 206 def reflected_endpoint connection.get(:__reflected_endpoint) end
reflects_specific_object?(object_name)
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 210 def reflects_specific_object?(object_name) ( self.class.__object_name.name == object_name && ( connection.get(:__endpoint_name) == :show || connection.get(:__endpoint_name) == :edit ) ) || parent_resource_named?(object_name) end
resource_with_name(object_name, context = self.class)
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 226 def resource_with_name(object_name, context = self.class) if context.__object_name&.name == object_name context elsif context.parent resource_with_name(object_name, context.parent) end end
verify_nested_data(nested, context)
click to toggle source
# File lib/pakyow/reflection/extensions/controller.rb, line 234 def verify_nested_data(nested, context) local = self nested.each do |object| context.required object.name do optional local.data.public_send(object.plural_name).source.class.primary_key_field object.attributes.each do |attribute| if attribute.required? required attribute.name else optional attribute.name end end local.__send__(:verify_nested_data, object.nested, self) end end end