Skip to content
CAI
Software that uses CAICheck a score

alexreisner/geocoder

67.8

Adequate · 26 September 2026

9.7k

lines of production code

Ruby

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Ruby gem that provides geocoding and reverse-geocoding capabilities for applications, supporting a wide array of external lookup services and local IP-to-location databases. It integrates with major ORMs like ActiveRecord and Mongoid to store and query geographic data, while offering tools for coordinate conversion, distance calculations, and asynchronous processing. The library also includes a command-line interface and Rake tasks to facilitate bulk geocoding operations and the management of local MaxMind database data.

How it got here

2009–2011 — Modular architecture and ORM expansion

13 changes.

The project underwent a major architectural refactor to replace its monolithic structure with a modular system, introducing dedicated support for multiple ORMs like ActiveRecord, Mongoid, and MongoMapper. This period also expanded functionality through new geocoding providers, a command-line interface, caching mechanisms, and comprehensive test infrastructure.

2012–2021 — Testing expansion and caching refactoring

8 changes.

This period focused on significantly expanding test coverage for core functionality and a wide array of geocoding providers, alongside adding comprehensive unit tests for lookups and database schemas. Concurrently, the library introduced a modular, extensible cache store architecture with Redis TTL support and added Rails generators for MaxMind database migrations to enhance local IP-to-location mapping capabilities.

Features

Add Geocoder configuration generator

Introduces a new Rails generator that creates a default initializer file at config/initializers/geocoder.rb. This initializer provides a commented-out template for configuring geocoding options (such as timeout, lookup service, and proxy settings), exception handling, calculation preferences (units and distance methods), and cache configuration (expiration and prefix), allowing users to easily scaffold and customize the library's behavior in their applications.

lib/generators/geocoder/config · high confidence

Add command-line interface for geocoding

The application now includes executable scripts in the bin directory to allow users to interact with the geocoding functionality from the command line. The bin/console script provides an interactive IRB session with the Geocoder library pre-loaded, optionally configuring API keys from an api\_keys.yml file if present. The bin/geocode script allows users to run geocoding commands directly via the Geocoder CLI.

bin · high confidence

Add generators for MaxMind GeoLite City and Country database migrations

Users can now generate database migrations to store MaxMind GeoLite City and Country data locally. This change introduces new Rails generators (\geolite\_city\ and \geolite\_country\) and corresponding migration templates that create tables for IP-to-location mapping (City) and IP-to-country mapping (Country), complete with necessary indexes for query performance. A shared helper module ensures the generated migrations are compatible with Rails 5+ versioning conventions.

lib/generators/geocoder/maxmind · high confidence

Add support for Abstract API geocoding service

Users can now geocode IP addresses using the Abstract API service by configuring the \:abstract\_api\ lookup. This new provider requires an \api\_key\ and supports HTTPS requests to the Abstract API IP geolocation endpoint.

lib/geocoder/lookups · high confidence

Add support for AbstractAPI geocoding service

Introduces a new result class for the AbstractAPI geocoding service, exposing location details (city, state, country, postal code), security indicators (VPN detection), timezone information, flag assets, currency data, and connection metadata (ISP, ASN) to users.

lib/geocoder/results · high confidence

Geocoder library restructured with new CLI, caching, and calculation modules

The lib/geocoder directory has been reorganized into distinct modules, introducing a new command-line interface (CLI) for direct geocoding lookups, a dedicated caching system (Cache, CacheStore) for storing results, and a Calculations module for distance and bearing math. Configuration is now managed via a singleton Configuration class with a DSL, and the library version is set to 1.8.6. This refactoring separates concerns like IP address validation, request handling, and SQL generation into their own files, improving maintainability and adding new capabilities like CLI usage and result caching.

lib/geocoder · high confidence

Initial project structure and documentation setup

Establishes the foundational repository structure by adding comprehensive documentation (README, API Guide, Changelog, Contributing guidelines) and standardizing project metadata (LICENSE, .gitignore). It also refactors the build system by replacing deprecated Rake tasks with Bundler and modern RDoc configuration, and updates the initialization hook to explicitly require the geocoder library.

(repo-wide) · high confidence

New Rake tasks for geocoding and MaxMind data loading

Added new Rake tasks to support geocoding workflows and MaxMind database management. The \lib/tasks/geocoder.rake\ file introduces a \geocode:all\ task that allows users to geocode or reverse-geocode model objects, with support for batching (via \BATCH\ environment variable), limiting results (\LIMIT\), adding delays (\SLEEP\), and specifying the target model class (\CLASS\). The \lib/tasks/maxmind.rake\ file adds a suite of tasks under \geocoder:maxmind:geolite\ to download, extract, and insert MaxMind GeoLite City or Country data into the application, handling archive extraction via the \rubyzip\ gem and delegating database insertion to the \MaxmindDatabase\ module.

lib/tasks · high confidence

New examples for custom lookups, cache bypass, and async reverse geocoding

Added three new example files to demonstrate advanced usage patterns: app\_defined\_lookup\_services.rb shows how to define and register custom lookup services with separate API keys; cache\_bypass.rb provides a Geocoder::CacheBypass class to handle cache unavailability by either raising or swallowing errors; and reverse\_geocode\_job.rb illustrates an ActiveJob implementation for asynchronous reverse geocoding that handles Timeout::Error and SocketError exceptions.

examples · high confidence

Removals

Removal of empty geocoder rake task file

The placeholder rake task file for geocoding operations has been removed from the project. This cleanup eliminates an unused file that contained only commented-out code, simplifying the task structure without affecting any active geocoding functionality.

tasks · high confidence

Architecture

Refactored geocoder stores into a modular Store module hierarchy

The geocoder library has restructured its ORM integrations by introducing a \Geocoder::Store\ namespace with a \Base\ module and specific implementations for ActiveRecord, MongoDB, and MongoMapper. This change replaces the previous flat structure, allowing shared logic (such as coordinate handling and geocoding lookups) to be reused across different database adapters while maintaining distinct scope definitions for each ORM. Users will see no functional change in how they define geocoded models, but the internal organization is now more modular and extensible.

lib/geocoder/stores · high confidence

Behavioural changes

Major architectural refactor and new coordinate conversion support

The library has been restructured into a modular architecture with separate files for configuration, logging, query handling, calculations, and model integrations (ActiveRecord, Mongoid, MongoMapper), replacing the previous monolithic implementation. This refactor introduces a new \Geocoder::EastingNorthing\ class that converts UK Ordnance Survey Easting/Northing coordinates to WGS84 latitude/longitude, and adds a \MaxmindDatabase\ module to handle downloading and inserting MaxMind GeoLite CSV data into local databases. The core search API is now driven by a \Geocoder::Query\ object, and the library now supports multiple geocoding lookups beyond the original Google service.

lib · high confidence

New extensible cache store architecture with Redis TTL support

The geocoder library introduces a new, extensible caching system built around a \Base\ class and specific implementations. A new \Generic\ cache store is added, which automatically adapts to different underlying store APIs (supporting \\[\]=\, \set\, or \write\ for writing, and \\[\]\, \get\, or \read\ for reading). Additionally, a dedicated \Redis\ cache store is provided, which supports setting expiration times (TTL) via the \expiration\ option. This change replaces the previous monolithic caching implementation with a modular structure that allows for easier extension and more specific behavior for different backends.

_lib/geocoder/cache\stores · high confidence

Refactored geocoder model integration into modular store-based architecture

The geocoder model layer has been restructured from a monolithic implementation into a modular system where each ORM (ActiveRecord, Mongoid, MongoMapper) is handled by its own dedicated module. This change introduces a shared base module for common initialization logic and separates ORM-specific store integrations, allowing for cleaner configuration of geocoding options such as units, method, lookup, language, and params. It also adds support for skipping automatic index creation in MongoDB-based models via the skip\_index option and ensures compatibility with Mongoid 3.x indexing syntax while maintaining backward compatibility with earlier versions.

lib/geocoder/models · high confidence

Test coverage

Added test database schema migration; Comprehensive unit test suite for geocoding core functionality; Establish test infrastructure for ActiveRecord and Mongoid models; Expanded test coverage for geocoding lookups; Test fixtures added for Abstract API, Amap, Amazon Location Service, Azure, Baidu, BAN Data Gouv FR, Bing, CloudMade, DB-IP.com, ESRI, FreeGeoIP, Geoapify, Geocoder.ca, Geocod.io, Geoportail.lu, and more.

Dependencies

Add Rails 5.0 compatibility support

A new Gemfile (gemfiles/Gemfile.rails5.0) has been added to support testing against Rails 5.0.1. This configuration pins the Rails version and includes necessary dependencies for development and testing, such as Mongoid 6.1.0, specific database adapters (SQLite3, PostgreSQL, MySQL), and platform-specific gems for JRuby and Rubinius.

gemfiles · high confidence

Initial gem specification and development dependencies

The project now includes a formal gemspec (geocoder.gemspec) and a Gemfile to manage its distribution and development environment. The gemspec defines the package metadata, sets a minimum Ruby version of 2.5.0, and declares runtime dependencies on 'base64' and 'csv'. The Gemfile configures development and test dependencies, including Rails 5.1.x, various database adapters (SQLite3, MySQL2, PostgreSQL), and testing tools like Webmock and Test-Unit.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 50 → 68 (+18.1)
  • Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 99 → 98 (-1.4)
  • Architecture 94 → 99 (+4.9)
  • Maturity 55 → 54 (-1.8)
  • Readiness 25 → 62 (+36.9)
  • Security 80 → 99 (+19.0)

Resolved (8)

  • Coverage not measured — test suite did not build
  • Dimension evaluation failed
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • No exposed public API
  • No tests found
  • Test reliability not included

New (32)

  • Base.fetch_raw_data (cognitive 16) (lib/geocoder/lookups/base.rb)
  • Calculations.extract_coordinates (cognitive 16) (lib/geocoder/calculations.rb)
  • ClassMethods.near_scope_options (cognitive 17) (lib/geocoder/stores/active_record.rb)
  • Documentation: contradicts the code
  • Duplicate configuration entry points. 'Geocoder.configure' delegates to or is identical to 'Configuration.configure', exposing two ways to do the same thing.
  • Duplicate type definition with confusing naming. 'MyPreciousss' appears to be a duplicate or alias of 'Lookup' with a non-standard, likely internal or test-specific name that leaks into the public API surface.
  • Duplicated block (12 lines × 2) (lib/generators/geocoder/maxmind/geolite_city_generator.rb)
  • Duplicated block (12 lines × 3) (lib/geocoder/lookups/freegeoip.rb)
  • Duplicated block (33 lines × 2) (lib/geocoder/lookups/ipinfo_io.rb)
  • Duplicated block (53 lines × 2) (lib/geocoder/results/nationaal_georegister_nl.rb)
  • Duplicated block (7 lines × 2) (lib/geocoder/results/geoapify.rb)
  • Duplicated block (8 lines × 2) (lib/geocoder/stores/active_record.rb)
  • Duplicated block (8 lines × 3) (lib/geocoder/lookups/ip2location.rb)
  • Esri.results (cognitive 16) (lib/geocoder/lookups/esri.rb)
  • Further sole-owners (lower concentration)
  • HackComment (test/unit/lookups/ipdata_co_test.rb)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Inconsistent access patterns for service categorization. 'street_services' and 'ip_services' are exposed as both methods and properties, which is redundant and inconsistent with other methods like 'get'.
  • Inconsistent cache access patterns. The 'Cache' class uses Ruby's bracket notation (read/write via [] and []=), while the underlying 'CacheStore' implementations use explicit 'read' and 'write' methods. This inconsistency between the facade and the implementation is confusing.
  • …and 12 more

Changes since last survey

  • 2 commits — 2 feature/other, 0 fixes

By area

  • (repo) — 1 commit
  • (root) — 1 commit

Notable commits

  • change: Allow configuring the cache with a cache store instance
  • change: Merge pull request #1711 from pioz/cache-store-instance

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

alexreisner/geocoder was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit c10bd701215110ebe65da1c8b8b410b124208fd2 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-d0929f7ac71f.