jgaskins / perpetuity

Persistence gem for Ruby objects using the Data Mapper pattern
http://jgaskins.org/blog/2012/04/20/data-mapper-vs-active-record/
MIT License
250 stars 14 forks source link

Detecting attributes from model #51

Closed reneklacan closed 10 years ago

reneklacan commented 10 years ago

Hi, I have implemented automatic attributes detection from model, what do you think about it?

Let's have a model

class Book
  include Virtus.model

  attribute :title
  attribute :price
  attribute :description
end

# or

class Book
  attr_accessor :title, :price, :description

  def self.attributes
    [:title, :price, :description]
  end
end

After this change you can write mapper

class BookMapper < Perpetuity::Mapper
  map Book
  detect_attributes
end

Instead of

class BookMapper < Perpetuity::Mapper
  map Book
  attribute :title
  attribute :price
  attribute :description
end

It can be extended to detect also attribute types and other attribute options.

jgaskins commented 10 years ago

I can absolutely appreciate the desire not to duplicate the attributes list in the domain model and in the mapper, but while this will work for the MongoDB adapter, but won't work for Postgres, where types are necessary in order to determine the column type for each attribute. I'd prefer to keep the basic operations (such as attributes and basic queries) portable across data sources.

I want to implement adapter-specific mapper extensions for the various DB adapters so that we can do aggregations and map/reduce on MongoDB or full-text search on Postgres. Something like this would be a perfect candidate for that. In fact, if we wanted to detect attributes on a document store like MongoDB, we could just save all of the instance variables.

reneklacan commented 10 years ago

It think that type for Posthres could be also detected from Virtus attribute types

For example:

class User
  include Virtus.model

  attribute :name, String, required: true
  attribute :age, Integer
  attribute :birthdate, DateTime
  attribute :score, Float, default: 0
end

It is very easy to map Virtus types to Postgres types.

Are you still against it?

jgaskins commented 10 years ago

Unfortunately, yes, still against it. Virtus is a fantastic library, but this would be a built-in feature that depends on another gem.

There is a virtus-perpetuity gem that provides this bridge between the two gems, I believe.

On Thursday, August 21, 2014, René Klačan notifications@github.com wrote:

It think that type for Posthres could be also detected from Virtus attribute types

For example:

class User attribute :name, String, required: true attribute :age, Integer attribute :birthdate, DateTime attribute :score, Float, default: 0end

It is very easy to map Virtus types to Postgres types.

Are you still against it?

— Reply to this email directly or view it on GitHub https://github.com/jgaskins/perpetuity/pull/51#issuecomment-52986461.

reneklacan commented 10 years ago

You are right. I probably meant https://github.com/boochtek/virtus-perpetuity