{"id":29082503,"url":"https://github.com/seuros/activerecord-postgis","last_synced_at":"2026-03-07T05:33:10.995Z","repository":{"id":296642087,"uuid":"868512230","full_name":"seuros/activerecord-postgis","owner":"seuros","description":"PostGIS extension for ActiveRecord's PostgreSQL adapter. Adds spatial types and queries to Rails 8+ with zero configuration.","archived":false,"fork":false,"pushed_at":"2026-01-08T18:56:37.000Z","size":186,"stargazers_count":27,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-18T00:22:19.567Z","etag":null,"topics":["activerecord","activerecord-extension","database","geodata","geography","geometry","geos","geospatial","gis","orm","postgis","postgresql","rails","rails-gem","rails8","rgeo","ruby","spatial","spatial-data","spatial-database"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seuros.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-06T15:19:02.000Z","updated_at":"2026-01-08T18:56:40.000Z","dependencies_parsed_at":"2025-07-21T10:06:10.374Z","dependency_job_id":"535b6642-fe3f-48c8-8147-7380690930ea","html_url":"https://github.com/seuros/activerecord-postgis","commit_stats":null,"previous_names":["seuros/activerecord-postgis"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/seuros/activerecord-postgis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Factiverecord-postgis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Factiverecord-postgis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Factiverecord-postgis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Factiverecord-postgis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seuros","download_url":"https://codeload.github.com/seuros/activerecord-postgis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seuros%2Factiverecord-postgis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30208731,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T05:23:27.321Z","status":"ssl_error","status_checked_at":"2026-03-07T05:00:17.256Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activerecord","activerecord-extension","database","geodata","geography","geometry","geos","geospatial","gis","orm","postgis","postgresql","rails","rails-gem","rails8","rgeo","ruby","spatial","spatial-data","spatial-database"],"created_at":"2025-06-27T20:37:48.183Z","updated_at":"2026-03-07T05:33:10.960Z","avatar_url":"https://github.com/seuros.png","language":"Ruby","readme":"# ActiveRecord::PostGIS\n\n**The next-generation PostGIS adapter for Rails** - clean, modern, and built for the future.\n\n## Why This Gem?\n\nThis is the **next-generation PostGIS adapter** that brings PostGIS support to Rails the right way:\n\n✅ **Use standard `postgres://` URLs** - No custom adapter names, no special configuration  \n✅ **No monkey patching** - Clean extensions using Rails 8 patterns  \n✅ **No obscure hacks** - Transparent, well-documented implementation  \n✅ **Latest APIs** - Built for Rails 8+ and Ruby 3.3+  \n✅ **Zero configuration** - Just add the gem and it works  \n\nUnlike legacy PostGIS adapters that require custom database URLs, special configurations, and complex setup, this gem **extends the existing PostgreSQL adapter** seamlessly. Your database configuration stays clean and standard.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'activerecord-postgis'\n```\n\nAnd then execute:\n\n```\n$ bundle install\n```\n\nOr install it yourself as:\n\n```\n$ gem install activerecord-postgis\n```\n\n## Configuration\n\n**Zero configuration required!** Just use your standard PostgreSQL database configuration:\n\n```yaml\n# config/database.yml\ndevelopment:\n  adapter: postgresql\n  url: postgres://user:password@localhost/myapp_development\n  # That's it! No special adapter, no custom configuration\n```\n\n## Usage\n\n### Migrations\n\nCreate spatial columns using PostGIS types:\n\n```ruby\nclass CreateLocations \u003c ActiveRecord::Migration[8.0]\n  def change\n    create_table :locations do |t|\n      t.st_point :coordinates, srid: 4326\n      t.st_polygon :boundary, geographic: true\n      t.st_line_string :route, has_z: true\n      t.timestamps\n    end\n  end\nend\n```\n\n### Spatial Queries\n\n**With RGeo Objects** (Recommended):\n\n```ruby\n# Create RGeo geometries\nfactory = RGeo::Geographic.spherical_factory(srid: 4326)\npoint = factory.point(-5.923647, 35.790897)  # Cap Spartel, Tangier, Morocco\npolygon = factory.polygon(...)\n\n# Direct queries with RGeo objects\nLocation.where(coordinates: point)\nLocation.where(\"ST_Distance(coordinates, ?) \u003c ?\", point, 1000)\n\n# Using parameterized queries (automatically quoted)\nlocations_nearby = Location.where(\n  \"ST_DWithin(coordinates, ?, ?)\", \n  point, \n  1000  # meters\n)\n\n# Complex spatial queries\nparks_in_city = Park.where(\n  \"ST_Within(boundary, ?)\", \n  city_polygon\n)\n```\n\n**With Arel Spatial Methods** (Now with expanded arsenal!):\n\n```ruby\n# Basic spatial queries\nLocation.where(\n  Location.arel_table[:coordinates].st_distance(point).lt(1000)\n)\n\n# NEW: K-Nearest Neighbor - Lightning fast \"find nearest\" queries\n# Uses spatial index for incredible performance!\nnearest_locations = Location\n  .order(Location.arel_table[:coordinates].distance_operator(my_position))\n  .limit(10)\n\n# Advanced spatial predicates\n# Find intersecting routes\nRoute.where(Route.arel_table[:path].st_intersects(restricted_zone))\n\n# Find points within efficient distance (uses spatial index!)\nLocation.where(\n  Location.arel_table[:coordinates].st_dwithin(headquarters, 5000)\n)\n\n# Create buffer zones\nsafe_zones = DangerZone.select(\n  DangerZone.arel_table[:area].st_buffer(100).as('safety_perimeter')\n)\n\n# Transform between coordinate systems\nglobal_coords = Location.select(\n  Location.arel_table[:local_position].st_transform(4326).as('wgs84_position')\n)\n\n# Calculate areas\nterritories = Region.select(\n  Region.arel_table[:boundary].st_area.as('territory_size')\n)\n```\n\n**With WKT Strings**:\n\n```ruby\n# Using Well-Known Text format\nLocation.where(\n  \"ST_Distance(coordinates, ST_GeomFromText(?)) \u003c ?\",\n  \"POINT(-5.923647 35.790897)\",\n  1000\n)\n```\n\n### Model Integration\n\n```ruby\nclass Location \u003c ApplicationRecord\n  # Works automatically - no configuration needed\n  # Spatial attributes are automatically parsed and serialized\nend\n\nlocation = Location.create!(\n  coordinates: \"POINT(-5.923647 35.790897)\"  # Tangier, Morocco\n)\n\nputs location.coordinates.x  # -5.923647\nputs location.coordinates.y  # 35.790897\n```\n\n## Testing\n\nWhen testing spatial functionality in your Rails application, this gem provides helpful test utilities:\n\n```ruby\n# In your test_helper.rb or rails_helper.rb\nrequire 'activerecord-postgis/test_helper'\n\nclass ActiveSupport::TestCase\n  include ActiveRecordPostgis::TestHelper\nend\n\n# Or for RSpec\nRSpec.configure do |config|\n  config.include ActiveRecordPostgis::TestHelper\nend\n```\n\n### Test Helper Methods\n\n```ruby\nclass LocationTest \u003c ActiveSupport::TestCase\n  def test_spatial_operations\n    # Create test geometries\n    point1 = create_point(-5.9, 35.8)\n    point2 = create_point(-5.91, 35.81)\n    polygon = create_test_polygon\n    \n    location = Location.create!(coordinates: point1, boundary: polygon)\n    \n    # Traditional assertions\n    assert_spatial_equal point1, location.coordinates\n    assert_within_distance point1, point2, 200  # meters\n    assert_contains polygon, point1\n    \n    # New chainable syntax (recommended)\n    assert_spatial_column(location.coordinates)\n      .has_srid(4326)\n      .is_type(:point)\n      .is_geographic\n      \n    assert_spatial_column(location.boundary)\n      .is_type(:polygon)\n      .has_srid(4326)\n  end\n  \n  def test_3d_geometry\n    point_3d = create_point(1.0, 2.0, srid: 4326, z: 10.0)\n    \n    assert_spatial_column(point_3d)\n      .has_z\n      .has_srid(4326)\n      .is_type(:point)\n      .is_cartesian\n  end\nend\n```\n\n**Available Test Helpers:**\n\n**Traditional Assertions:**\n- `assert_spatial_equal(expected, actual)` - Assert spatial objects are equal\n- `assert_within_distance(point1, point2, distance)` - Assert points within distance\n- `assert_contains(container, contained)` - Assert geometry contains another\n- `assert_within(inner, outer)` - Assert geometry is within another\n- `assert_intersects(geom1, geom2)` - Assert geometries intersect\n- `assert_disjoint(geom1, geom2)` - Assert geometries don't intersect\n\n**Chainable Spatial Column Assertions:**\n- `assert_spatial_column(geometry).has_z` - Assert has Z dimension\n- `assert_spatial_column(geometry).has_m` - Assert has M dimension\n- `assert_spatial_column(geometry).has_srid(srid)` - Assert SRID value\n- `assert_spatial_column(geometry).is_type(type)` - Assert geometry type\n- `assert_spatial_column(geometry).is_geographic` - Assert geographic factory\n- `assert_spatial_column(geometry).is_cartesian` - Assert cartesian factory\n\n**Geometry Factories:**\n- `create_point(x, y, srid: 4326)` - Create test points\n- `create_test_polygon(srid: 4326)` - Create test polygons  \n- `create_test_linestring(srid: 4326)` - Create test linestrings\n- `factory(srid: 4326, geographic: false)` - Get geometry factory\n- `geographic_factory(srid: 4326)` - Get geographic factory\n- `cartesian_factory(srid: 0)` - Get cartesian factory\n\n## Documentation\n\n📚 **Learn Like You're Defending the Galaxy**\n\n- [🚀 Spatial Warfare Manual](docs/SPATIAL_WARFARE.md) - Advanced PostGIS arsenal explained through space combat\n- [🍳 The PostGIS Cookbook](docs/COOKBOOK.md) - Real-world recipes from delivery fleets to geofencing\n\n## Features\n\n🌍 **Complete PostGIS Type Support**\n- `st_point`, `st_line_string`, `st_polygon` \n- `st_multi_point`, `st_multi_line_string`, `st_multi_polygon`\n- `st_geometry_collection`, `st_geography`\n- Support for SRID, Z/M dimensions\n\n🔍 **Spatial Query Methods**\n- Core methods: `st_distance`, `st_contains`, `st_within`, `st_length`\n- **NEW:** Advanced spatial operations:\n  - `\u003c-\u003e` (distance_operator) - K-Nearest Neighbor search (blazing fast!)\n  - `st_intersects` - Detect geometry intersections\n  - `st_dwithin` - Efficient proximity queries (index-optimized!)\n  - `st_buffer` - Create buffer zones around geometries\n  - `st_transform` - Convert between coordinate systems\n  - `st_area` - Calculate polygon areas\n- Custom Arel visitor for PostGIS SQL generation\n- Seamless integration with ActiveRecord queries\n\n⚡ **Modern Architecture**\n- Built on Rails 8 patterns\n- Clean module extensions (no inheritance)\n- Proper type registration and schema dumping\n- Compatible with multi-database setups\n\n🛠️ **Developer Experience**\n- Standard `postgres://` URLs\n- Works with existing PostgreSQL tools\n- Clear error messages and debugging\n- Full RGeo integration\n- Comprehensive test helpers for spatial assertions\n\n## Acknowledgments\n\nThis gem builds upon the incredible work of many contributors to the Ruby geospatial ecosystem:\n\n🙏 **RGeo Ecosystem** - The foundation that makes Ruby geospatial possible:\n- [RGeo](https://github.com/rgeo/rgeo) originally by Daniel Azuma, currently maintained by Keith Doggett (@keithdoggett) and Ulysse Buonomo (@BuonOmo)\n- [RGeo::ActiveRecord](https://github.com/rgeo/rgeo-activerecord) for ActiveRecord integration\n- [RGeo::Proj4](https://github.com/rgeo/rgeo-proj4) for coordinate system transformations\n- Former maintainer Tee Parham and all contributors who built this ecosystem\n\n🗺️ **PostGIS Pioneers** - Previous PostGIS adapters that paved the way:\n- [activerecord-postgis-adapter](https://github.com/rgeo/activerecord-postgis-adapter) by Daniel Azuma and the RGeo team\n- All the maintainers and contributors who solved spatial data challenges in Rails\n\n🌍 **PostGIS \u0026 GEOS** - The underlying spatial powerhouses:\n- PostGIS developers for the amazing spatial database extension\n- GEOS contributors for computational geometry\n- PostgreSQL team for the solid foundation\n\nThis gem exists because of their pioneering work. I'm simply bringing it into the modern Rails era with cleaner patterns and zero configuration.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/seuros/activerecord-postgis.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseuros%2Factiverecord-postgis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseuros%2Factiverecord-postgis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseuros%2Factiverecord-postgis/lists"}