Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Attributes #334

Merged
merged 9 commits into from
Mar 4, 2021
Merged

Support Attributes #334

merged 9 commits into from
Mar 4, 2021

Conversation

keithdoggett
Copy link
Member

@keithdoggett keithdoggett commented Feb 11, 2021

This adds support for the standard Postgresql attributes and RGeo features as attributes.

Changes:

  • Set the adapter name as postgresql in the type module that is used for determining which types ActiveRecord should use. This fixes Unknown type Jsonb when using Attributes API.  #267 and Unable to create an attribute for an array #284. Now users won't have to redefine Postgres attributes if they want them available in their app, but the downside is that if custom types were registered under postgis they will have to be changed to postgresql.
  • Change the OID::Spatial module to accept keywords as arguments (geo_type, srid, has_z, has_m, geographic) instead of oid and sql_type. This is a necessary step to allow RGeo features as attributes because attributes access the type directly and do not pass a sql_type in.
  • Modify initialize_type_map to parse sql_type then define the OID for each column.
  • Register all RGeo column types as attributes using OID::Spatial.

With these changes, we can define attributes like this:

class SpatialClass < ActiveRecord::Base
  attribute :geo_point, :st_point, srid: 4326, geographic: true
end

and it doesn't need an associated column in the database.

Importantly, this allows for the proper joining of spatial data (#210), although it is not seamless yet. In order to properly format RGeo features from a join, the spatial column needs to be re-defined as an attribute on the target table. For example:

class SpatialFoo < ActiveRecord::Base
 belongs_to :foo

 # has column geo_point (:st_point, srid: 4326, geographic: true)
end

class Foo < ActiveRecord::Base
 has_one :spatial_foo
 
 # re-define geo_point here so join works
 attribute :geo_point, :st_point, srid: 4326, geographic: true
end

# perform a query where geo_point is joined to foo
foo = Foo.joins(:spatial_foo).select("foos.id, spatial_foos.geo_point").first
p foo.geo_point.class
# => RGeo::Geographic::SphericalPointImpl
p foo.geo_point.srid
# => 4326

TODO:

  • Add support for attributes
  • Update README with examples
  • Update History

Copy link
Member

@BuonOmo BuonOmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still some todos left on README, and history to update. I've also made some comments, mostly questions to make sure I understood the code correctly.

def initialize(oid, sql_type)
@sql_type = sql_type
@geo_type, @srid, @has_z, @has_m = self.class.parse_sql_type(sql_type)
def initialize(geo_type: 'geometry', srid: 0, has_z: false, has_m: false, geographic: false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation should be updated as well

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point I'll do that!

lib/active_record/connection_adapters/postgis/type.rb Outdated Show resolved Hide resolved
Comment on lines +69 to +71
# TODO: The attributes that will be joined have to be defined on the
# model we make the query with. Ideally, it would "just work" but
# at least this workaround makes joining functional.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you plan anything for that ? 🙂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll open up an issue once this is approved 😅

@keithdoggett keithdoggett assigned BuonOmo and unassigned keithdoggett Feb 22, 2021
Copy link
Member

@BuonOmo BuonOmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks great, I added one last review, tell me what you think about it. Otherwise we'll be ready to merge soon 😄

lib/active_record/connection_adapters/postgis/type.rb Outdated Show resolved Hide resolved
@BuonOmo BuonOmo assigned keithdoggett and unassigned BuonOmo Feb 26, 2021
Copy link
Member

@BuonOmo BuonOmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Great work, thank you 💪

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unknown type Jsonb when using Attributes API.
2 participants