Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Zeus is a work in progress to abstract the DB away in a separate hierarchy.

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 spec
Octocat-spinner-32 .document
Octocat-spinner-32 .gitignore
Octocat-spinner-32 LICENSE
Octocat-spinner-32 README.rdoc
Octocat-spinner-32 Rakefile
README.rdoc

Zeus - the database abstraction library

Following James Golick's jamesgolick.com/2010/3/14/crazy-heretical-and-awesome-the-way-i-write-rails-apps.html, I thought I could implement something similar, without too much hassle.

NOTE: no code exists at the moment. These are only ideas.

Examples

# Sinatra, but Rails could use the same implementation
get "/posts" do
  @posts = Zeus.posts
  render :posts_index
end

get "/post/:id" do
  @post = Zeus.posts.filter(:id => params[:id]).first
  render :post
end

post "/posts" do
  post = Post.new
  post.title        = params[:post][:title]
  post.body         = params[:post][:body]
  post.published_at = Time.now.utc

  Zeus.persist(post)
end

post "/post/:id/comments" do
  post = Zeus.posts.filter(:id => params[:id]).first
  comment = post.add_comment(params[:comment].merge(:ip => request.env["HTTP_REAL_IP"])

  # Single DB transaction inserts both rows in the database
  Zeus.persist(post, comment)
end

class Post
  def initialize
    @comments = []
  end

  def add_comment(attributes)
    comment = Comment.new
    comment.author_name  = attributes[:name]
    comment.author_email = attributes[:email]
    comment.body         = attributes[:body]
    comment.author_ip    = attributes[:ip]
    @comments << comment

    comment
  end
end

class Comment
end

post = Post.new
post.title = "Zeus is a new library"

Zeus.configure do |config|
  config.model :post, :table_name => "posts" do
    string   :title
    text     :body
    integer  :comments_count
    datetime :published_at
    datetime :created_at, :updated_at, :null => false

    index :published_at

    # A single argument for the block receives the Post object defined in the domain model.
    before_create do |domain_post|
      domain_post.created_at = Time.now.utc
    end

    # Accepting 2 arguments receives both the domain model instance, and the persistence model.
    before_save do |domain_post, zeus_post|
      zeus_post.comments_count = domain_post.comments.length
      domain_post.updated_at = zeus_post.updated_at = Time.now.utc
    end
  end

  # Convention over configuration
  config.model :comment do
    integer  :post_id, :references => :posts
    string   :author_name, :author_email, :author_ip
    text     :body
    float    :spaminess
    datetime :approved_at
    datetime :created_at, :null => false

    index :post_id, :created_at, :approved_at
  end
end

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don't break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright © 2010 François Beausoleil. See LICENSE for details.

Something went wrong with that request. Please try again.