class Cuprum::Rails::Routes

Represent the routes available for a given resource.

Attributes

base_path[R]

@return [String] the relative path of the resource.

wildcards[R]

@return [String] the url wildcards for the resource.

Public Class Methods

new(base_path:, &block) click to toggle source

@param base_path [String] The relative path of the resource.

# File lib/cuprum/rails/routes.rb, line 79
def initialize(base_path:, &block)
  @base_path = base_path
  @wildcards = {}

  singleton_class.instance_exec(&block) if block_given?
end
route(action_name, path) click to toggle source

Defines a route for the resource routes.

Each defined route creates a helper method on the routes, which returns the full path of the resource route. A member action helper (if the path ends in an :id wildcard) will require passing in either the primary key of the member or the member entity.

If the base path includes wildcards, then the wildcards must be set (using with_wildcards) before calling a route helper.

@param action_name [String, Symbol] The name of the action. @param path [String] The path of the action relative to the resource

root. If the path has a leading slash, the path is treated as an
absolute path and does not include the routes base path.
# File lib/cuprum/rails/routes.rb, line 26
def route(action_name, path)
  validate_action_name!(action_name)
  validate_path!(path)

  if member_route?(path)
    define_member_route(action_name, path)
  else
    define_collection_route(action_name, path)
  end
end

Private Class Methods

define_collection_route(action_name, original_path) click to toggle source
# File lib/cuprum/rails/routes.rb, line 39
def define_collection_route(action_name, original_path)
  define_method :"#{action_name}_path" do
    path = resolve_base_path(original_path)

    insert_wildcards(path)
  end
end
define_member_route(action_name, original_path) click to toggle source
# File lib/cuprum/rails/routes.rb, line 47
def define_member_route(action_name, original_path)
  define_method :"#{action_name}_path" do |entity|
    path = resolve_base_path(original_path)

    insert_wildcards(path, entity)
  end
end
member_route?(path) click to toggle source
# File lib/cuprum/rails/routes.rb, line 55
def member_route?(path)
  path.split('/').include?(':id')
end
validate_action_name!(action_name) click to toggle source
# File lib/cuprum/rails/routes.rb, line 59
def validate_action_name!(action_name)
  unless action_name.is_a?(String) || action_name.is_a?(Symbol)
    raise ArgumentError,
      'action_name must be a String or Symbol',
      caller(1..-1)
  end

  return unless action_name.to_s.empty?

  raise ArgumentError, "action_name can't be blank", caller(1..-1)
end
validate_path!(path) click to toggle source
# File lib/cuprum/rails/routes.rb, line 71
def validate_path!(path)
  return if path.is_a?(String) || path.is_a?(Symbol)

  raise ArgumentError, 'path must be a String or Symbol', caller(1..-1)
end

Public Instance Methods

parent_path() click to toggle source

@return [String] the path to the parent resource index.

# File lib/cuprum/rails/routes.rb, line 93
def parent_path
  root_path
end
root_path() click to toggle source

@return [String] the root path for the application.

# File lib/cuprum/rails/routes.rb, line 98
def root_path
  '/'
end
with_wildcards(wildcards) click to toggle source

@param wildcards [Hash] The wildcards to use with the routes.

@return [Cuprum::Rails::Routes] a copy of the routes with the wildcards.

# File lib/cuprum/rails/routes.rb, line 105
def with_wildcards(wildcards)
  unless wildcards.is_a?(Hash)
    raise ArgumentError, 'wildcards must be a Hash'
  end

  clone.apply_wildcards(wildcards)
end

Protected Instance Methods

apply_wildcards(wildcards) click to toggle source
# File lib/cuprum/rails/routes.rb, line 115
def apply_wildcards(wildcards)
  @wildcards = wildcards.stringify_keys

  self
end

Private Instance Methods

insert_wildcards(path, entity = nil) click to toggle source
# File lib/cuprum/rails/routes.rb, line 123
def insert_wildcards(path, entity = nil)
  path
    .split('/')
    .map do |segment|
      next segment unless segment.start_with?(':')

      next resolve_primary_key(entity) if segment == ':id'

      resolve_wildcard(segment)
    end
    .join('/')
end
resolve_base_path(path) click to toggle source
# File lib/cuprum/rails/routes.rb, line 136
def resolve_base_path(path)
  return path if path.start_with?('/')

  return base_path if path.empty?

  "#{base_path}/#{path}"
end
resolve_primary_key(entity) click to toggle source
# File lib/cuprum/rails/routes.rb, line 144
def resolve_primary_key(entity)
  raise MissingWildcardError, 'missing wildcard :id' if entity.nil?

  primary_key = entity.class.primary_key

  entity[primary_key]
end
resolve_wildcard(segment) click to toggle source
# File lib/cuprum/rails/routes.rb, line 152
def resolve_wildcard(segment)
  wildcard = segment[1..] # :something_id to something_id

  return wildcards[wildcard] if wildcards.include?(wildcard)

  wildcard = segment[1...-3] # :something_id to something

  if wildcards.include?(wildcard)
    return resolve_primary_key(wildcards[wildcard])
  end

  raise MissingWildcardError, "missing wildcard #{segment}"
end