Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 15, 2013
@elight Added example from test_data.rb
Annotated with information to explain test_data.rb
f823bb3
@elight API change requires a new major version. Crazy going to 1.0 on someth…
…ing this untried but API change and semantic versioning...
09577b7
Showing with 124 additions and 1 deletion.
  1. +123 −0 README.md
  2. +1 −1  lib/edr/version.rb
View
123 README.md
@@ -5,6 +5,129 @@
Blog post describing EDR: ["Building Rich Domain Models in Rails. Separating Persistence"](http://engineering.nulogy.com/posts/building-rich-domain-models-in-rails-separating-persistence).
+# Description
+
+Originally named for "Entity, Data, Repository", building on the [Repository pattern](http://martinfowler.com/eaaCatalog/repository.html).
+
+# Example
+
+Lifted from <code>spec/test_data.rb</code>:
+
+## STEP0: Schema
+``` ruby
+ActiveRecord::Schema.define(:version => 1) do
+ create_table "orders", :force => true do |t|
+ t.decimal "amount"
+ t.date "deliver_at"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ create_table "items", :force => true do |t|
+ t.string "name"
+ t.decimal "amount"
+ t.integer "order_id"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+end
+```
+
+## STEP1: Define data objects
+``` ruby
+class OrderData < ActiveRecord::Base
+ self.table_name = "orders"
+
+ attr_accessible :amount, :deliver_at
+
+ validates :amount, numericality: true
+ has_many :items, class_name: 'ItemData', foreign_key: 'order_id'
+end
+
+class ItemData < ActiveRecord::Base
+ self.table_name = "items"
+
+ attr_accessible :amount, :name
+
+ validates :amount, numericality: true
+ validates :name, presence: true
+end
+```
+
+## STEP2: Define Domain Model
+
+Fields and associations on the Domain Model are determined via ActiveRecord reflection. The Domain Model is coupled to its ActiveRecord class by naming convention.
+
+Domain Model classes should share the same name as the AR classes except they should not end in "Data". So OrderData < ActiveRecord::Base maps to the Order domain
+model class.
+
+Be aware that your Domain Model test/specs will need to stub/mock out dependencies upon their Repository and other Domain Model objects. That is, you Domain Model instances will lack fields or associations in their tests. This is because Domain Model objects are [POROs](http://blog.jayfields.com/2007/10/ruby-poro.html) until they are registered with edr at runtime. As you should not want to test the framework, this should facilitate testing your Domain Model and your persistence in isolation from one another and from the edr framework.
+
+``` ruby
+class Order
+ def add_item attrs
+ repository.create_item self, attrs
+ end
+end
+
+class Item
+end
+```
+
+## STEP3: map data objects to domain objects
+
+You probably want the below in a config/initializers/edr.rb
+
+``` ruby
+Edr::Registry.map_models_to_mappers
+```
+
+
+## STEP4: Define repository to access data
+
+Your Repositories arbitrate persistence on behalf of the Domain Model.
+While it is not ideal for the Domain Model to be aware of the Repository,
+we're stuck with this unless we add a [Unit of Work] reification to
+manage the relationship between the Domain Model and the Repository
+
+``` ruby
+module OrderRepository
+ extend Edr::AR::Repository
+
+ set_model_class Order
+
+ def self.find_by_amount amount
+ where(amount: amount)
+ end
+
+ def self.find_by_id id
+ where(id: id).first
+ end
+
+ def self.create_item order, attrs
+ item = ItemRepository.create_item(order, attrs)
+ data(order).reload
+ return item
+ end
+
+ module ItemRepository
+ extend Edr::AR::Repository
+ set_model_class Item
+
+ def self.create_item order, attrs
+ item = Item.build(attrs)
+ item.order_id = order.id
+ persist item
+ end
+ end
+end
+```
+
+
+# STEP5: Profit
+# --------------------------------------------------
+```
+
## Installation
Add this line to your application's Gemfile:
View
2  lib/edr/version.rb
@@ -1,3 +1,3 @@
module Edr
- VERSION = "0.0.5"
+ VERSION = "1.0.0"
end

No commit comments for this range

Something went wrong with that request. Please try again.