Skip to content

Instantly share code, notes, and snippets.

@snusnu
Created August 5, 2009 02:01
Show Gist options
  • Save snusnu/162436 to your computer and use it in GitHub Desktop.
Save snusnu/162436 to your computer and use it in GitHub Desktop.
# This is all you need to setup datamapper on a given repository
# (the sqlite3 in memory adapter in this case).
#
# If you ever happen to feel the need to report a ticket for datamapper,
# it greatly helps the developers if you wrap a drilled down example
# that demonstrates your error in the same format that's used here.
# If someone asks you to put together a standalone script that demonstrates
# the error, it should roughly look like this file you're currently reading
#
# Everyone can just run this file by issuing: "ruby filename.rb"
# ----------------- datamapper setup -----------------------
require 'rubygems'
require 'dm-core'
DataMapper::Logger.new(STDOUT, :debug)
DataMapper.setup(:default, 'sqlite3::memory:')
# ---------------- define your models ----------------------
class Person
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :projects
has n, :tasks, :through => :projects, :via => :tasks # currently FAILS if :via => :tasks is missing
end
class Department
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :projects
end
class Project
include DataMapper::Resource
property :id, Serial
property :name, String
belongs_to :department
belongs_to :person
has n, :tasks
end
class Task
include DataMapper::Resource
property :id, Serial
property :name, String
belongs_to :project
end
# ---------------- migrate the database --------------------
DataMapper.auto_migrate!
# --------------- demonstrate something --------------------
puts '-'*80
# Create related resources on the fly by specifying their attributes
#
# This could probably be useful when dealing with input that comes from forms in a web application
# Be sure to checkout the dm-accepts_nested_attributes if you want more control (updating and deleting)
# over your related resources. This too is especially handy when dealing with input that comes from
# forms in web applications
Person.create(:projects => [ { :department => { :name => 'dke' } } ])
# Or if you have the related parent already handy
department = Department.create(:name => 'swe')
Person.create(:projects => [ { :department => department } ])
# Creating arbitrarily deep object trees in one go
#
# Be aware of the following things:
# - The child objects (Task.new) must either already exist, or be created on the fly
# It is not possible to call Task.create instead of Task.new in that situation
# This is because of the way ruby operates from "right to left"
# Create a person and 1 related project with 1 related task
person = Person.create(:projects => [ Project.new(:department => department, :tasks => [ Task.new ]) ])
project = person.projects.first
# Create a person, relate 1 existing project and create a related project with 1 related task
person = Person.create(:projects => [ project, Project.new(:department => department, :tasks => [ Task.new ]) ])
# Create related resources either as objects or by supplying their attributes
person = Person.create
project = Project.create(:person => person, :department => { :name => 'ssw' }, :tasks => [ Task.new ])
task = project.tasks.first
# Use in queries
#
# This also demonstrates the fact that the statements below
# will not issue a query immediately, but will wait with that
# until you actually access the resources in question
# which happens in the call to query.inspect below
# Have a look at the generated SQL to get a feeling for how
# smart the queries generated by datamapper are.
query_1 = Project.all(:person => person, :tasks => task)
query_2 = Project.all(:person => person, :tasks => [ task ])
query_3 = Project.all(:person => person, :tasks => Task.all)
query_4 = Project.all(:person => person, :tasks => Task.first)
puts "query_1 result = #{query_1.inspect}"
puts "query_2 result = #{query_2.inspect}"
puts "query_3 result = #{query_3.inspect}"
puts "query_4 result = #{query_4.inspect}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment