Skip to content

Latest commit

 

History

History
executable file
·
135 lines (111 loc) · 6.08 KB

README.textile

File metadata and controls

executable file
·
135 lines (111 loc) · 6.08 KB

dm-is-commentable

A DataMapper plugin that adds the ability to comment any model.
It also allows for easy rating of comments by using dm-is-rateable.
For a deeper understanding on how it does it’s thing, please consult
the code itself, and of course the specs.


# DEPENDENCIES (taken from dm-is-commentable.rb)

# require 'dm-core'
# require 'dm-types'
# require 'dm-timestamps'
# require 'dm-validations'
# require 'dm-aggregates'
# require 'dm-is-remixable'
# require 'dm-is-rateable' # only for rateable commenting

class User
  include DataMapper::Resource
  property :id, Serial
end

class Trip

  include DataMapper::Resource
  
  property :id, Serial
  
  # Customization via properties
  #
  # add these properties if you wish to be able to toggle some behaviour.
  # dm-is-commentable will recognize these properties and behave accordingly
  # you can use any combination of these properties, or all, or none of them
  # Currently you MUST name these properties like this, but this will likely
  # change in the near future.
  #
  # property :commenting_enabled,           Boolean #, :nullable => false, :default => true
  # property :anonymous_commenting_enabled, Boolean #, :nullable => false, :default => true
  # property :rateable_commenting_enabled,  Boolean #, :nullable => false, :default => true

  # Customization via options:
  #
  # options = {
  #   # Options for generated remixable
  #   # -------------------------------
  #   # Use :name and :type to name the fk property and give it a type
  #   # Pass all other options on to the 'property' call
  #   :commenter => { :name => :user_id, :type => Integer, :nullable => false }, 
  #   # Use :type to change the type of the comment body property
  #   # Pass all other options on to the 'property' call
  #   :body      => { :type => DataMapper::Types::Text, :nullable => false },
  #   # Set this to true to make all comments rateable (but not togglable)
  #   # If 'property :rateable_commenting_enabled' is defined on this model,
  #   # it will take precedence over the option defined here.
  #   # Alternatively, you can also pass all options supported by dm-is-rateable
  #   :rateable  => false,
  #   # Options for remixer
  #   # -------------------
  #   # Set the specified alias (Symbol) on the 'comments' association
  #   :as         => nil,
  #   # class_name to use for the generated remixed model
  #   :class_name => "#{self}Comment"
  # }.merge(options)
  
  is :commentable #, options

  # will define and thus be able to auto_migrate! by using dm-is-remixable:
  #
  # class TripComment
  #   include DataMapper::Resource
  #   
  #   property :id, Serial
  #   
  #   property :trip_id, Integer, :nullable => false
  #   property :user_id, Integer, :nullable => false
  #   property :body,    Text,    :nullable => false
  #
  #   property :created_at, DateTime
  #   property :updated_at, DateTime
  #
  #   belongs_to :trip
  #   belongs_to :user
  # end
  
end

dm-is-remixable

The actual reason why I chose dm-is-remixable (over some kind of polymorphic associations)
is because I actually don’t like polymorphic relationships that much! Call me old fashioned
but I like my tables with proper referential integrity all setup, and I don’t like
to store the same 5 strings a million times. Maybe one could refactor STI to use a type_id column instead
of storing the same String over and over, maybe denormalization is fine here too, I don’t know.
Anyways, this wouldn’t change the actual problem with referential integrity.

I also really don’t see any problem with the “pure relational” approach that dm-is-remixable follows.
You don’t get to see all those boring join models in you app/models directory, still they get stored
in the repository and everything behaves right.

I don’t care wether this leads to a few more tables in my repository, because I normally
don’t have to interact with them using SQL. Even if I was using SQL,
the table layout would be perfectly clear and queries would be easy to write.

I also cannot see too many negative impacts on query performance, since the only use case that would really benefit
from one big table, is a query over some comments of ALL commentable types.
Now this won’t happen very often! At least not in my system … I don’t show different types of comments on one page,
even if I would, I would “accept” these few more queries.

The pain I felt with those numerous join models that cluttered my app/models directory
instantly went away with dm-is-remixable. I think it’s a great plugin that greatly
helps narrowing the gap between relational and oop styles!

That said, a commenting plugin for datamapper that does its thing using polymorphic relations
would definitely enrich the datamapper ecosystem and thus would be a good thing! People could choose for themselves!
I’m quite sure though, that I’m not the one to provide it, because I don’t have a use case for it at the moment.

polymorphic associations

A possible use case where I think that using polymorphic associations in a commenting plugin would make more sense,
would be a commenting system, where an admin user should have the possibilty to turn ANY model into a commentable,
I would go with the polymorphic associations approach here, for 2 reasons:

1. I don’t like to give the user CREATE/DROP priviliges (necessary for auto_migrate!),
and I don’t like to generate tables dynamically in general.

2. I wouldn’t want to “prepare” comment tables for every single instance,
because then even I would have the feeling that there’s too many tables :-)

Again, this is a usecase I can imagine, but I guess that’s a rather “uncommon” one.
Nevertheless, a dm commenting plugin that would use polymorphic associations would easily scratch that itch!
Possibly, more pure relational approaches also exist to solve this kind of problem? Think about it if you need it!