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

v3.0.0 Refactor #86

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

krainboltgreene
Copy link

This is the pull request for discussing the next major version of recommendable.

These are the feature's we'd like to have for the next version:

recommendable-core

  • Defines the main user-facing API for Recommendable
  • Contains default (but overridable) collaborative filtering logic. Uses Sets provided either by Ruby's Stdlib or, if too slow, native extensions.

recommendable-<database>

  • Modular gems that tell other recommendable components where to store and fetch ratings from.

recommendable-<ORM>

  • Modular gems that tell other recommendable components how to query for the Model records themselves

@davidcelis
Copy link
Owner

The way I've been thinking of making Recommendable more modular would be to split it up into multiple gems. My initial thoughts are a structure somewhat like...

  • recommendable-core would define the overall API of the gem as well as the default collaborative filtering algorithms. This would probably use Ruby sets as first, but it would be nicer if it were a core extension written in C (and Java for JRuby support) for speed purposes.
  • recommendable-postgresql would define that ratings should be stored in Postgres.
  • recommendable-redis would define that ratings should be stored in Redis, but would also override the collaborative filtering methods to utilize Redis' data types.
  • recommendable-activerecord would define that the models themselves are using ActiveRecord
  • The existing recommendable gem would be a meta-gem that depends on recommendable-core, recommendable-redis, and recommendable-activerecord

However, this might get pretty complicated. For example, should ORM support really be extracted out into separate gems as well? How else could we handle ratings and the actual models being stored in separate data stores? I essentially assume an ORM is being used to deal with Models and I still feel that's a safe assumption.

@krainboltgreene
Copy link
Author

I think this is probably the best approach to this sort of thing, especially since it allows people to pop in and easily contribute to their area of expertise/use.

I'd like to suggest making the repositories based off my blankgem since it gives us a head start on development environments.

I essentially assume an ORM is being used to deal with Models and I still feel that's a safe assumption.

Agreed, in fact I'd say it's probably also safe to just assume our target is using ActiveModel. There really haven't been any ORMs that don't use ActiveModel, except maybe the up-and-coming ROM.rb.

@davidcelis
Copy link
Owner

Sure; though I'm mostly concerned with the query interface, which changes enough between ORMs that we've gotta handle that. I'm not terribly fond of my current case statement that just switches on the detected ORM and queries accordingly, though it is only a few lines of code. Then again, separating that out into multiple gems that focus on an individual ORM would probably allow for a better way of defining the recommends :things and resulting dynamic method finders (e.g. liked_things, disliked_things as what would be considered real relationships by the ORM.

This is another thing I've wanted, a more ActiveRecord style approach to those relationships. It would be nice to define those the same way you'd define a has_many relationship and with similar options. Then that call could utilize the ORM's built-in relation support and define them sensibly.

@krainboltgreene
Copy link
Author

This is largely what I wanted when I thought about modularizing the postgres bits. What do you want as a first step? Extracting the math/functions (core) or extracting the orm parts?

@davidcelis
Copy link
Owner

I think extracting core is gonna be difficult, because I'm still not entirely certain exactly what will go in there. I'm pretty certain that the logic to compare users and generate recommendations is going to be a lot slower if I do the set math using Ruby's Set stdlib. The Java core ext would probably be straightforward, since Java provides both a Set and SortedSet interface. But I'm also not a C programmer so making the main core extension would be time consuming. The ORM logic is currently small enough that we could extract it easily and build on it, but figuring out how to extract the recommendation logic in a sane way is something I want to tackle sooner rather than later.

@davidcelis
Copy link
Owner

Perhaps a C++ extension would be more sane? It has sets and they can be ordered.

Another option would be a C extension that uses the JudyHS structure

@krainboltgreene
Copy link
Author

I agree, but have no experience with C++ extensions.

@davidcelis davidcelis force-pushed the master branch 2 times, most recently from df82439 to cde49e0 Compare March 12, 2015 02:53
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.

2 participants