Skip to content

Instantly share code, notes, and snippets.

@jodosha
Last active August 29, 2015 14:00
Show Gist options
  • Save jodosha/11404253 to your computer and use it in GitHub Desktop.
Save jodosha/11404253 to your computer and use it in GitHub Desktop.
Lotus::Repository: class vs instance methods

Given that an adapter brings its own query API, the implementation of the finders depends on the interface of the current adapter's query.

class ArticleRepository
  include Lotus::Repository

  def self.most_recent(limit = 5)
    query do
      desc(:created_at)
    end.limit(limit)
  end
end

The implementation of .most_recent won't work if .query doesn't return a query object that responds to #desc and #limit.

So if we do: ArticleRepository.adapter = yaml_adapter the call to .most_recent will raise a NoMethodError. Of course, I made the assumption here that an hypothetical YamlAdapter::Query doesn't implement SQL concepts like #desc.

To overcome this problem, I was thinking to have a different semantic: instead of an assigment to use a DSL + a registry.

Lotus::Model.register_adapter :sql, SqlAdapter.new(...), default: true
Lotus::Model.register_adapter :yaml, YamlAdapter.new(...)

# this defaults to :sql
class ArticleRepository
  include Lotus::Repository
end

class CommentRepository
  include Lotus::Repository
  adapter :yaml
end

Because of this dependency problem, I'm afraid that we should stick with class methods for Lotus::Repository.

class ArticleRepository
  include Lotus::Repository

  def initialize(adapter)
    @adapter = adapter
  end

  def most_recent(limit = 5)
    query do
      desc(:created_at)
    end.limit(limit)
  end
end

ArticleRepository.new(sql_adapter).most_recent # works fine
ArticleRepository.new(yaml_adapter).most_recent # blows up

What do you think?

@apohllo
Copy link

apohllo commented Apr 29, 2014

class ConfigRepository
  include Lotus::Repository
  adapter :yaml
end

But how would you interpret:

ConfigRepository.most_recent

This doesn't make sense in that context. Correct me if I am wrong. Or maybe I misunderstood your example.

@jeremyf
Copy link

jeremyf commented Apr 29, 2014

@apohllo It would raise an exception. And I believe that would be okay; A linter for an adapter would be useful. Not to fail specs but to add warnings about the adapter. Alternatively, would it make sense to provide an inline override capability?

class ConfigRepository
  include Lotus::Repository
  adapter :yaml do
    def limit(limit)
      # Inline override
    end
  end
end

@jodosha
Copy link
Author

jodosha commented Apr 30, 2014

@apohllo I've update the example by renaming ConfigRepository to CommentRepository.
In the code above I wanted to show how different repositories can have different data sources.

Of course CommentRepository doesn't implement .most_recent, because it has nothing to do with ArticleRepository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment