CARVIEW |
Select Language
HTTP/2 302
server: nginx
date: Fri, 08 Aug 2025 08:58:57 GMT
content-type: text/plain; charset=utf-8
content-length: 0
x-archive-redirect-reason: found capture at 20180611012147
location: https://web.archive.org/web/20180611012147/https://github.com/jabley/dm-core
server-timing: captures_list;dur=0.527548, exclusion.robots;dur=0.019731, exclusion.robots.policy;dur=0.010088, esindex;dur=0.011925, cdx.remote;dur=17.413206, LoadShardBlock;dur=153.612692, PetaboxLoader3.datanode;dur=42.909797, PetaboxLoader3.resolve;dur=54.021416
x-app-server: wwwb-app217
x-ts: 302
x-tr: 192
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
set-cookie: wb-p-SERVER=wwwb-app217; path=/
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
HTTP/2 200
server: nginx
date: Fri, 08 Aug 2025 08:58:58 GMT
content-type: text/html; charset=utf-8
x-archive-orig-server: GitHub.com
x-archive-orig-date: Mon, 11 Jun 2018 01:21:47 GMT
x-archive-orig-transfer-encoding: chunked
x-archive-orig-status: 200 OK
x-archive-orig-cache-control: no-cache
x-archive-orig-vary: X-PJAX
x-archive-orig-set-cookie: logged_in=no; domain=.github.com; path=/; expires=Fri, 11 Jun 2038 01:21:47 -0000; secure; HttpOnly
x-archive-orig-set-cookie: _gh_sess=ZEppYjRNNWE5YWVQQlpUckpudkQraWIwcXVsRWlEV041WVFGWlc0T25kM1pDTFd1RW1kM04xaDlKbjVTZTZWNWxtUGVGRno2VHR5TXNLeDJQR2x4aXEvUEl5ejYyakpNVlJncFVtc3RpYmxzckFFNVV5bTViUGhLUm96VXJCZFgxK01zUDBGOFZQZG03alMxc2NCWDBIQTZON25RL0NXdExBdGxwNzRIWFB0a0g2bUgycER2TWRxcDVhU01aUmZpeGpCR042ZHBZRzlUakkzK0tKR2lZeDNhU3ZydmlpSjVyWFRLZ1plbmxVYmM1SGc0TVhMTlcxL2hzRWMwa2UxTlBGRElTN0FpTHJEOEl3N1hOUG9yOWhpazZDZUNtTmhqL3pBbHRTY1hGY3ludVU1R0dyWFRkaEhLS01XZkFvTWY5SWtQY1ZIWUpDeG9JV3pBNmo3RFRIZE56VDJwc3VDY1FuWXdKcjZWVlBkYTlDa0pQdDV6ZlpENkwzY29pODJMczA3UFExeVAvOXFZKzNxdm5pTW9YWm1sWkdmWEliaGQ5MGM4bUk1eUxBdz0tLUltWkVMZ1RTVzhDTjZ6NkxhakFYR3c9PQ%3D%3D--7d1ee86d528852c26803619aa53a606876674897; path=/; secure; HttpOnly
x-archive-orig-x-request-id: 51c30b53-295b-4bde-9349-6c19509085c0
x-archive-orig-x-runtime: 0.354421
x-archive-orig-strict-transport-security: max-age=31536000; includeSubdomains; preload
x-archive-orig-x-frame-options: deny
x-archive-orig-x-content-type-options: nosniff
x-archive-orig-x-xss-protection: 1; mode=block
x-archive-orig-expect-ct: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors"
x-archive-orig-content-security-policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' uploads.github.com status.github.com collector.githubapp.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com wss://live.github.com; font-src assets-cdn.github.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; frame-src render.githubusercontent.com; img-src 'self' data: assets-cdn.github.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com *.githubusercontent.com; manifest-src 'self'; media-src 'none'; script-src assets-cdn.github.com; style-src 'unsafe-inline' assets-cdn.github.com
x-archive-orig-x-runtime-rack: 0.364354
x-archive-orig-x-github-request-id: 9AC8:58F8:4257CB4:7FF1D48:5B1DCEAB
x-archive-guessed-content-type: text/html
x-archive-guessed-charset: windows-1250
memento-datetime: Mon, 11 Jun 2018 01:21:47 GMT
link: ; rel="original", ; rel="timemap"; type="application/link-format", ; rel="timegate", ; rel="first memento"; datetime="Mon, 11 Jun 2018 01:21:47 GMT", ; rel="memento"; datetime="Mon, 11 Jun 2018 01:21:47 GMT", ; rel="next memento"; datetime="Mon, 07 Sep 2020 04:20:50 GMT", ; rel="last memento"; datetime="Mon, 07 Sep 2020 04:21:06 GMT"
content-security-policy: default-src 'self' 'unsafe-eval' 'unsafe-inline' data: blob: archive.org web.archive.org web-static.archive.org wayback-api.archive.org athena.archive.org analytics.archive.org pragma.archivelab.org wwwb-events.archive.org
x-archive-src: archiveteam_github_20180703084006/archiveteam_github_20180703084006.megawarc.warc.gz
server-timing: captures_list;dur=3.988717, exclusion.robots;dur=0.035020, exclusion.robots.policy;dur=0.016848, esindex;dur=0.020150, cdx.remote;dur=17.760476, LoadShardBlock;dur=235.697193, PetaboxLoader3.datanode;dur=465.114580, PetaboxLoader3.resolve;dur=268.519230, load_resource;dur=579.738263
x-app-server: wwwb-app217
x-ts: 200
x-tr: 979
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
content-encoding: gzip
GitHub - jabley/dm-core: DataMapper - Core
Fetching latest commit…
Permalink
Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
DataMapper - Core
https://datamapper.org/
Clone or download
Launching GitHub Desktop...
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop...
If nothing happens, download GitHub Desktop and try again.
Launching Xcode...
If nothing happens, download Xcode and try again.
Launching Visual Studio...
If nothing happens, download the GitHub extension for Visual Studio and try again.
Pull request
Compare
This branch is 2242 commits behind datamapper:master.

Cannot retrieve the latest commit at this time.
Failed to load latest commit information. | |||
![]() |
lib | ||
![]() |
script | ||
![]() |
spec | ||
![]() |
tasks | ||
![]() |
.autotest | ||
![]() |
.gitignore | ||
![]() |
CONTRIBUTING | ||
![]() |
FAQ | ||
![]() |
History.txt | ||
![]() |
MIT-LICENSE | ||
![]() |
Manifest.txt | ||
![]() |
QUICKLINKS | ||
![]() |
README.txt | ||
![]() |
Rakefile | ||
![]() |
SPECS | ||
![]() |
TODO | ||
![]() |
dm-core.gemspec |
README.txt
:include:QUICKLINKS = Why DataMapper? == Open Development DataMapper sports a very accessible code-base and a welcoming community. Outside contributions and feedback are welcome and encouraged, especially constructive criticism. Make your voice heard! Submit a ticket[https://wm.lighthouseapp.com/projects/4819-datamapper/overview] or patch[https://wm.lighthouseapp.com/projects/4819-datamapper/overview], speak up on our mailing-list[https://groups.google.com/group/datamapper/], chat with us on irc[irc://irc.freenode.net/#datamapper], write a spec, get it reviewed, ask for commit rights. It's as easy as that to become a contributor. == Identity Map One row in the data-store should equal one object reference. Pretty simple idea. Pretty profound impact. If you run the following code in ActiveRecord you'll see all <tt>false</tt> results. Do the same in DataMapper and it's <tt>true</tt> all the way down. @parent = Tree.find(:first, :conditions => ['name = ?', 'bob']) @parent.children.each do |child| puts @parent.object_id == child.parent.object_id end This makes DataMapper faster and allocate less resources to get things done. == Dirty Tracking When you save a model back to your data-store, DataMapper will only write the fields that actually changed. So it plays well with others. You can use it in an Integration data-store without worrying that your application will be a bad actor causing trouble for all of your other processes. You can also configure which strategy you'd like to use to track dirtiness. == Eager Loading Ready for something amazing? The following example executes only two queries. zoos = Zoo.all first = zoos.first first.exhibits # Loads the exhibits for all the Zoo objects in the zoos variable. Pretty impressive huh? The idea is that you aren't going to load a set of objects and use only an association in just one of them. This should hold up pretty well against a 99% rule. When you don't want it to work like this, just load the item you want in it's own set. So the DataMapper thinks ahead. We like to call it "performant by default". This feature single-handedly wipes out the "N+1 Query Problem". No need to specify an <tt>include</tt> option in your finders. == Laziness Can Be A Virtue Text fields are expensive in data-stores. They're generally stored in a different place than the rest of your data. So instead of a fast sequential read from your hard-drive, your data-store server has to hop around all over the place to get what it needs. Since ActiveRecord returns everything by default, adding a text field to a table slows everything down drastically, across the board. Not so with the DataMapper. Text fields are treated like in-row associations by default, meaning they only load when you need them. If you want more control you can enable or disable this feature for any field (not just text-fields) by passing a @lazy@ option to your field mapping with a value of <tt>true</tt> or <tt>false</tt>. class Animal include DataMapper::Resource property :name, String property :notes, Text, :lazy => false end Plus, lazy-loading of text fields happens automatically and intelligently when working with associations. The following only issues 2 queries to load up all of the notes fields on each animal: animals = Animal.all animals.each do |pet| pet.notes end == Plays Well With Others In ActiveRecord, all your fields are mapped, whether you want them or not. This slows things down. In the DataMapper you define your mappings in your model. So instead of an _ALTER TABLE ADD field_ in your data-store, you simply add a <tt>property :name, :string</tt> to your model. DRY. No schema.rb. No migration files to conflict or die without reverting changes. Your model drives the data-store, not the other way around. Unless of course you want to map to a legacy data-store. Raise your hand if you like seeing a method called <tt>col2Name</tt> on your model just because that's what it's called in an old data-store you can't afford to change right now? In DataMapper you control the mappings: class Fruit include DataMapper::Resource storage_names[:repo] = 'frt' property :name, String, :field => 'col2Name' end == All Ruby, All The Time It's great that ActiveRecord allows you to write SQL when you need to, but should we have to so often? DataMapper supports issuing your own query, but it also provides more helpers and a unique hash-based condition syntax to cover more of the use-cases where issuing your own SQL would have been the only way to go. For example, any finder option that's non-standard is considered a condition. So you can write <tt>Zoo.all(:name => 'Dallas')</tt> and DataMapper will look for zoos with the name of 'Dallas'. It's just a little thing, but it's so much nicer than writing <tt>Zoo.find(:all, :conditions => ['name = ?', 'Dallas'])</tt>. What if you need other comparisons though? Try these: Zoo.first(:name => 'Galveston') # 'gt' means greater-than. We also do 'lt'. Person.all(:age.gt => 30) # 'gte' means greather-than-or-equal-to. We also do 'lte'. Person.all(:age.gte => 30) Person.all(:name.not => 'bob') # If the value of a pair is an Array, we do an IN-clause for you. Person.all(:name.like => 'S%', :id => [1, 2, 3, 4, 5]) # An alias for Zoo.find(11) Zoo[11] # Does a NOT IN () clause for you. Person.all(:name.not => ['bob','rick','steve']) See? Fewer SQL fragments dirtying your Ruby code. And that's just a few of the nice syntax tweaks DataMapper delivers out of the box...
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.