Rails and alternative ORMs

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Notes on slide 1



    So ... Why use an ORM?

    Because your database and your OO code are unlike things. Different paradigms.



    So in a sense, any time you use a relational DB + OO, you’re going to do some sort of object relational mapping.



    May be formal or informal.



    So data types are not identical

    Your DB has a formal definition independent of the use of the data.

    This is a big one.



    In OO, you follow references - an object can “point” to another object, and so on.



    In SQL, you logically join sets of data together.

    Any bit of data can be joined to any other bit.



    In OO, ideal is to hide as much as you can and only expose a public interface.

    declarative vs. active - declare that certain kinds of data are acceptable, vs. actively checking at certain points in time.

    SQL doesn’t directly have a concept of inheritance. Fundamental to OO.



    Finally, different purposes.



    Define structure for data (and hold that data)



    vs.



    Doing something

    So basically, ORM are translators between unlike things. Like any translation,

    this isn’t going to be perfectly smooth, and there will always be tradeoffs.



    In this talk, Dan and I are going to talk about these tradeoffs by looking at three approaches to ORM with Ruby.

    You’re probably familiar with this already, so I won’t show much code here or talk about how to use AR. Instead, let’s talk for a few minutes at a more theoretical level.

    In this pattern, an object wraps each DB row. This single object handles both domain logic and database access. What's unique about this?

    Other approaches might not treat each row as an object, or might combine multiple rows into a single object.

    Others might separate these, filtering the data through a logic layer, instead of exposing both side-by-side.





    class User < ActiveRecord::Base
    end



    That does a _lot_. And from looking at this, you have no idea exactly what it did. You have to check the db schema in order to figure that out.



    The good news is that convention dominates. Once you know the conventions, you generally aren't surprised.

    This is true, by default. N+1, loads all columns, etc.



    It would be really nice if it could do these things.



    But at the same time, it provides facilities for these sorts of optimizations.


    This is part of the reason that alternative ORMs got started.



    The thing is, it isn't true any more. At least not entirely.


    This guy, Josh Peek, made Rails 2.2 thread safe.

    And this guy, who you may recognize, added the current connection pooling.

    The fact is, as a AR developer, you can pretty much forget how to write a join.



    This isn't really a limitation of AR - some could say that it’s a feature. But at the same time, you really do need to know SQL if you’re going to use a relational database.



    That said, my SQL skills have atrophied as a Rails developer. On our newest project, Luke and I have had to do quite a bit of custom SQL, and we've tried to make our DB layer a bit smarter and more robust. Which leads to the next criticism...


    Rails makes polymorphic associations easy and multi-table inheritance hard.



    But polymorphic associations: bad idea. Cuts out a join table, but hurts referential integrity. But because it’s easy, you see a lot of it.



    Is this a valid criticism? It usually isn’t that hard to fight against AR’s conventions, and most of the time, you don’t want to.

    This is bad. Basically, foreign keys require a plugin. Redhill. This plugin works, but isn't all that actively maintained, and some things (constraints) aren't even supported by that.



    You can always run a bare connection.execute() statement, but this won't get dumped into your schema.rb file, which is bad.



    According to DHH et al, you don't need DB constraints, and you want a dumb DB.










    4. Access your database directly.



    Company 1 may not exist.



    Or



    I.e. you make a mistake

    I.e. you make a mistake.



    This probably isn’t a problem for you, but it might be for some of the other people you work with.

    Sequel is a thread-safe DB library with a lightweight ORM








    Follows the ActiveRecord pattern

    So you don’t have to write much real SQL

    So you don’t have to write much real SQL

    The Sequel ORM is very similar to AR, at least on the surface.



    Does many of the things that Rails does, at least the basics.





    Also has similar support for sharding











































    Favorites, Groups & Events

    Rails and alternative ORMs - Presentation Transcript

    1. Rails and Alternative ORMs Dan Weinand Jonathan Dahl
    2. Why?
    3. DB vs. OO declarative vs. imperative
    4. DB vs. OO char/text vs. string
    5. DB vs. OO schema vs. _______
    6. DB vs. OO joins vs. pointers
    7. DB vs. OO public vs. encapsulated
    8. DB vs. OO constraints vs. validation
    9. DB vs. OO _____ vs. inheritance
    10. DB vs. OO DBA vs. programmer
    11. DB vs. OO structure vs. behavior
    12. http://www.engrish.com//wp-content/uploads/2008/08/hand-grenade.jpg
    13. 1. ActiveRecord
    14. An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. Martin Fowler, PoEAA, 160.
    15. One object per row.
    16. Data access and domain logic are done together.
    17. 6 Criticisms of ActiveRecord
    18. 1. Too much magic. http://cgi.ebay.com/MEDIEVAL-MAGE-KING-BLACK-TUNIC-COSTUME-SCA-LARP-_W0QQitemZ250373576829QQcmdZViewItemQQimsxZ20090215?IMSfp=TL090215143008r8810#ebayphotohosting
    19. class User < ActiveRecord::Base end
    20. 2. Not performant. http://www.flickr.com/photos/danprates/1418154518/
    21. 3. Not thread safe. No connection pooling. http://www.flickr.com/photos/streetmuseo/57990915/
    22. 4. Hides SQL from you. http://www.momentaryfascinations.com/entertainment/the.lost.monty.python.cartoon/still.5.jpg
    23. 5. Hard to fight against. http://www.mmonotebook.com/wp-content/uploads/2008/04/larp.jpg
    24. 6. Encourages stupid databases.
    25. 9 ways to bypass application-level constraints
    26. 1. Fixtures
    27. 2. Klass.delete(1)
    28. 3. record.save(false)
    29. 4.
    30. 5. Share DB with a second app
    31. 6. User.create(:company_id => 1)
    32. class User < ActiveRecord::Base 7. has_many :posts end
    33. 8. ActiveRecord::Base.connection.execute()
    34. 9. Errors in your app logic
    35. 2. Sequel
    36. An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. Martin Fowler, PoEAA, 160.
    37. Ruby DSL for SQL posts = DB[:posts] posts.filter(:category => /ruby/i, :author => [:jon, :dan]) posts.reverse_order(:created_at, :updated_at) posts.select(:title, :author) posts.limit(10)
    38. Ruby-like DSL for SQL posts.filter(:category => :ruby).order(:created_at).select(:title, :author)
    39. ORM class Post < Sequel::Model many_to_many :tags many_to_one :author validates_presence_of :title end post = Post[123] post.title # \"rails orms\" post.title = \"Rails ORMs\" post.save
    40. 3 interesting things sequel postgres://localhost:5432/myapp_development
    41. 3 interesting things require 'memcache' CACHE = MemCache.new 'localhost:11211', :namespace => 'blog' class Author < Sequel::Model set_cache CACHE, :ttl => 3600 end Author[333] # database hit Author[333] # cache hit
    42. 3 interesting things DB = Sequel.sqlite('app_test.db', :servers=>{:read_only=>{:host=>'slave_server'}})
    43. 3. Datamapper
    44. A layer of Mappers (473) that moves data between objects and a database while keeping them independent of each other and the mapper itself. Martin Fowler, PoEAA, 165.
    45. Multiple Databases • SQL-based • In-memory • Document-based • Search engines
    46. Explicit property mapping class Message include DataMapper::Resource property :name, String property :body, Text property :created_at, DateTime validates_presence_of :name end
    47. Get only the data you need
    48. Minimize the number of queries
    49. Save only the data that has changed
    50. Identity Map repository do @parent.children.each do |child| puts @parent.object_id = child.parent.object_id end end
    51. Ruby Query Syntax Zoo.first(:name.eql => 'Galveston') Person.all(:age.gt => 30) Person.all(:age.gte => 30) Person.all(:name.not => 'bob') Person.all(:name.like => 'S%', :id => [1,2,3,4,5]) Person.all(:name.not => ['bob','rick','steve']) Person.all(:order => [:age.desc])
    52. Chainable finders class Zoo def self.open all(:open => true) end def self.big all(:animal_count.gte => 1000) end end big_open_zoos = Zoo.big.open
    53. Associations class Article include DataMapper::Resource property :id, Serial property :title, String property :content, Text belongs_to :author end class Author include DataMapper::Resource property :id, Serial property :name, String has n, :articles end Article.all('author.name' => 'Michael')
    54. Implicit and explicit migrations
    55. Only basic functionality in core
    56. Gems for everything else
    57. Is it ready for primetime?
    58. Roadmap to 1.0
    59. Rails integration still lacking
    60. Not many production deployments
    61. Documentation sucks
    62. Some plugins still not ported
    63. Thanks! Dan Weinand Jon Dahl

    + jondahljondahl, 8 months ago

    custom

    690 views, 0 favs, 0 embeds more stats

    Most Rails users are familiar with ActiveRecord. Bu more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 690
      • 690 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 0
    • Downloads 12
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories