class JSONAPI::RelationshipsController
def active_storage_writable?(association)
def active_storage_writable?(association) self.class.respond_to?(:active_storage_attachment?) && active_storage_attachment?(@relationship_name, @resource.class) && association.nil? end
def destroy
def destroy authorize_resource_action!(@resource, action: :update, context: { relationship: @relationship_name }) relationship_data = parse_relationship_data return head :no_content if relationship_data.nil? remove_relationship(relationship_data) finalize_relationship_removal(relationship_data) rescue ArgumentError => e render_invalid_relationship_error(e) rescue JSONAPI::Errors::ParameterNotAllowed => e render_parameter_not_allowed_error(e) end
def ensure_relationship_writable!(association)
def ensure_relationship_writable!(association) return if active_storage_writable?(association) relationship_def = find_relationship_definition readonly = relationship_def && (relationship_def[:options] || {})[:readonly] == true JSONAPI::RelationshipGuard.ensure_writable!(association, @relationship_name, readonly:) end
def find_relationship_definition
def find_relationship_definition RelationshipHelpers.find_relationship_definition(@resource_class, @relationship_name) end
def parse_relationship_data
def parse_relationship_data raw_data = params[:data] return nil if raw_data.nil? return [] if raw_data.is_a?(Array) && raw_data.empty? return raw_data.map { |item| ParamHelpers.deep_symbolize_params(item) } if raw_data.is_a?(Array) ParamHelpers.deep_symbolize_params(raw_data) end
def polymorphic_association?
def polymorphic_association? RelationshipHelpers.polymorphic_association?(@resource_class, @relationship_name) end
def set_relationship_name
def set_relationship_name @relationship_name = params[:relationship_name].to_sym end
def show
def show authorize_resource_action!(@resource, action: :show, context: { relationship: @relationship_name }) render json: build_show_response, status: :ok end
def update
def update authorize_resource_action!(@resource, action: :update, context: { relationship: @relationship_name }) relationship_data = parse_relationship_data update_relationship(relationship_data) save_and_render_relationship(relationship_data) rescue ArgumentError => e render_invalid_relationship_error(e) rescue JSONAPI::Errors::ParameterNotAllowed => e render_parameter_not_allowed_error(e) end
def validate_relationship_exists
def validate_relationship_exists return if find_relationship_definition render_jsonapi_error( status: 404, title: "Relationship Not Found", detail: "Relationship '#{@relationship_name}' not found on #{@resource_name}", ) end