4. $ sudo gem install charesc
$ irb
>> $KCODE = quot;uquot;
>> require 'rubygems'
>> require 'charesc'
>> quot;charesc is made by Martin D#{U00FC}rstquot;
=> quot;charesc is made by Martin Dürstquot;
>> U00FC
=> quot;üquot;
>> quot;303274quot;
=> quot;üquot;
charesc
5. Active
Records
SELECT * FROM conferences WHERE (start_date > '2007-06-07')
# But, much nicer is...
6. Active
Records
SELECT * FROM conferences WHERE (start_date > '2007-06-07')
# But, much nicer is...
Conference.find(:all,
:conditions => [‘start_date > ?’,Date.today])
7. Active Records
SELECT conferences.quot;idquot; AS t0_r0,
conferences.quot;namequot; AS t0_r2, ...,
conference_sessions.quot;idquot; AS t1_r0,
conference_sessions.quot;conference_idquot; AS t1_r1, ...
FROM conferences
LEFT OUTER JOIN conference_sessions
ON conference_sessions.conference_id = conferences.id
WHERE (start_date < '2007-05-26')
# But, definitely easier and nicer is...
8. Active Records
SELECT conferences.quot;idquot; AS t0_r0,
conferences.quot;namequot; AS t0_r2, ...,
conference_sessions.quot;idquot; AS t1_r0,
conference_sessions.quot;conference_idquot; AS t1_r1, ...
FROM conferences
LEFT OUTER JOIN conference_sessions
ON conference_sessions.conference_id = conferences.id
WHERE (start_date < '2007-05-26')
# But, definitely easier and nicer is...
Conference.find(:all,
:conditions => ['start_date < ?', Date.today],
:include => :conference_sessions)
9. Sexy
Syntax
ActiveRecords
- no SQL
... + marshalling
to objects
11. Schemas
create_table :conferences do |t|
t.fkey :user
t.string :name, :limit => 50
t.text :description
t.date :start_date, :end_date
t.auto_dates
end
# instead of...
I can never
remember
SQL syntax
12. Schemas
create_table :conferences do |t|
t.fkey :user
t.string :name, :limit => 50
t.text :description
t.date :start_date, :end_date
t.auto_dates
end
# instead of...
Look up SQL on
I can never
remember
SQL syntax
13. Composite
Primary Keys
ProductHistory.find(:first, :conditions =>
['id = ? and start_date = ?', 56, Date.new(2000,5,5)])
# rather...
What about
Ruby syntax
improving on
other Ruby
syntax?
14. Composite
Primary Keys
ProductHistory.find(:first, :conditions =>
['id = ? and start_date = ?', 56, Date.new(2000,5,5)])
# rather...
ProductHistory.find(56, Date.new(2000,5,5))
What about
Ruby syntax
class ProductHistory < ActiveRecord::Base improving on
other Ruby
set_primary_keys :id, :start_date syntax?
end
15. What’s this do? #1
Nice syntax
can quickly tell
you want the
code will does
@user.conference_sessions_for(@conference)
16. What’s this do? #1
Nice syntax
can quickly tell
you want the
code will does
@user.conference_sessions_for(@conference)
# Returns all ConferenceSessions
# for a user at a conference
17. What’s this do? #2
@conference_attendees.map_id_and_login_and_full_name
20. What’s this do? #3
@to_user = @target_db::User.find(params[:id])
User.find(params[:id])
21. What’s this do? #3
@to_user = @target_db::User.find(params[:id])
User.find(params[:id])
@to_user.update(@from_db::User.find(params[:id]))
22. What’s this do? #3
@to_user = @target_db::User.find(params[:id])
User.find(params[:id])
@to_user.update(@from_db::User.find(params[:id]))
# Copies a User from one database to another
# see Magic Multi-Connection
# http://magicmodels.rubyforge.org
24. What’s this do? #1
Nice syntax
can quickly tell
you want the
code will does
@user.conference_sessions_for(@conference)
25. What’s this do? #1
Nice syntax
can quickly tell
you want the
code will does
@user.conference_sessions_for(@conference)
# Returns all ConferenceSessions
# for a user at a conference
26. What’s this do? #1
class User < ActiveRecord::Base
has_many :conference_sessions
def conference_sessions_for(conference)
conference_sessions.find(:all,
:conditions => ['conference_id = ?', conference])
end
end
No meta-magic, but it gives nice syntax
30. Cute ways to use #map
@users = User.find(:all)
@users.map {|user| user.login}
# => ['drnic', 'topfunky', 'dhh']
@users.map &:login
# => ['drnic', 'topfunky', 'dhh']
# but it gets ugly when you chain them...
@users.map(&:login).map(&:size)
# => [5, 8, 3]
31. Cute ways to use #map
# So, instead of...
@users.map(&:login).map(&:size)
# We might like...
@users.map_login.map_size
32. Remember find_by_xxx ?
def method_missing(method_id, *arguments)
pattern = /^find_(all_by|by)_([_a-zA-Z]w*)$/
if match = pattern.match(method_id.to_s)
finder = determine_finder(match)
# from active_record/base.rb, line 1190
33. Dissecting the request
def method_missing(method, *args, &block)
pattern = /(map|select|...)_by_([w_]+??)/
if (match = method.match(pattern))
iterator, callmethod = match[1], match[2]
# changed ‘find’ to ‘map’
# or select, reject, each, collect...
34. Iterating the request
# continued...
iterator, callmethod = match[1], match[2]
self.send(iterator) {|obj| obj.send callmethod }
# @array.map_by_foo
# callmethod => ‘foo’
# #foo invoked on each element of Array
35. Iterating many callmethods
# continued...
iterator, callmethod = match[1], match[2]
callmethods = callmethod.split('_and_')
callmethods.map do |callmethod|
self.send(iterator) {|obj| obj.send callmethod }
end
# @array.map_by_foo_and_bar
# callmethods => [‘foo’, ‘bar’]
# #foo and #bar invoked on each element of Array
37. map_by_method gem
# for complete source:
$ gem install map_by_method
$ mate $RUBYGEMS_PATH/map_by_method-0.6.0/lib/map_by_method.rb
# add the following to your ~/.irbrc
require 'map_by_method'
39. What’s this do? #3
@to_user = @target_db::User.find(params[:id])
User.find(params[:id])
40. What’s this do? #3
@to_user = @target_db::User.find(params[:id])
User.find(params[:id])
@to_user.update(@from_db::User.find(params[:id]))
41. What’s this do? #3
@to_user = @target_db::User.find(params[:id])
User.find(params[:id])
@to_user.update(@from_db::User.find(params[:id]))
# Copies a User from one database to another
# see Magic Multi-Connection
# http://magicmodels.rubyforge.org
43. MMC - alternate ideas
@db::User.find(params[:id])
# but I would have preferred...
User.find(params[:id]).from_db(@db)
44. MMC - alternate ideas
@db::User.find(params[:id])
# but I would have preferred...
User.find(params[:id]).from_db(@db)
# but we’d need FindProxies
# like AssociationProxies
46. class creator helper
class Module
def create_class(class_name, superclass = Object, &block)
klass = Class.new superclass, &block
self.const_set class_name, klass
end
end
>> module Connection; end
>> Connection.create_class 'User'
=> Connection::User
47. class creator helper
class Module
def create_class(class_name, superclass = Object, &block)
klass = Class.new superclass, &block
self.const_set class_name, klass
end
end
>> module Connection; end
>> Connection.create_class 'User'
=> Connection::User
@db::User
49. const_missing
class Module
alias :old_const_missing :const_missing
def const_missing(const_id)
return old_const_missing(const_id) rescue nil
target_class = quot;::#{const_id}quot;.constantize rescue nil
raise NameError.new(quot;bad constant #{const_id}quot;) unless target_class
create_class(const_id, target_class)
end
end
50. const_missing
class Module
alias :old_const_missing :const_missing
def const_missing(const_id)
return old_const_missing(const_id) rescue nil
target_class = quot;::#{const_id}quot;.constantize rescue nil
raise NameError.new(quot;bad constant #{const_id}quot;) unless target_class
create_class(const_id, target_class)
end
end
magic multi-connections
51. Picks up root classes
class Person; end
module Remote
establish_connection :other
end
>> Remote::Person.superclass
=> Person
52. const_missing
class Module
def const_missing(const_id)
return old_const_missing(class_id) rescue nil
table_name = DrNicMagicModels::Schema.models[const_id]
raise NameError.new(quot;bad constant #{const_id}quot;) unless table_name
create_class(class_id, ActiveRecord::Base) do
set_table_name table_name
end
end
end
“Does the class name match to a table name?”
53. const_missing
class Module
def const_missing(const_id)
return old_const_missing(class_id) rescue nil
table_name = DrNicMagicModels::Schema.models[const_id]
raise NameError.new(quot;bad constant #{const_id}quot;) unless table_name
create_class(class_id, ActiveRecord::Base) do
set_table_name table_name
end
end
dr nic’s magic models
end
“Does the class name match to a table name?”