rgeo / rgeo-activerecord

RGeo ActiveRecord extensions and tools for spatial connection adapters
Other
87 stars 64 forks source link

Create Scopes with Arel st_functions #61

Open keithdoggett opened 3 years ago

keithdoggett commented 3 years ago

It should be possible to create scopes on ActiveRecord models from the SpatialNamedFunctions. This would be in an optional module a user could include into their ActiveRecord model and it would allow access to these scopes.

This would make the SpatialNamedFunctions more accessible for users that are unfamiliar with Arel.

This would allow you to go from this:

pt = RGeo::Geos.factory.point(1,2)
locations = Location.arel_table
Location.select(:id, :geom).where(locations[:geom].st_contains(pt))

to:

pt = RGeo::Geos.factory.point(1,2)
Location.select(:id, :geom).st_contains(:geom, pt)
heka1024 commented 3 months ago

Hi, @keithdoggett. I'm interested in this issue!

BuonOmo commented 2 months ago

It seems that the above example using st_contains is in fact a simple case. Looking at the content of the tests (rg arel_table test/) we can see that sometimes we use where like in the example, sometimes we use find_by.

Also the example takes the simple case of st_contains, but st_distance for instance, should then be chained with a comparator (ex: .lt(2)) which makes the signature way more complicated.

Here's an example signature that would contain enough info:

Location.st_distance(:geom, pt, ->(x) { x.lt(2) })

I think it becomes harder to understand. The one below may already be a bit simpler:

Location.st(:geom, ->(x) { x.st_distance(pt).lt(2) })

But I feel like we are not really getting an advantage with the new writing. Also these two examples are not letting the user choose between where and find_by, we assume one of them, otherwise we'd need even one more argument.

With that said, I do not think that I have a convincing design yet for a generic solution. Someone has something better to offer? @heka1024 looking at you! Would you be our champion on this?