rom-rb 4.0 - Moscow, RailsClub 2017

rom-rb 4.0 - Moscow, RailsClub 2017

E864e5088627498df8f9b911a9bc3219?s=128

Piotr Solnica

September 23, 2017
Tweet

Transcript

  1. 6.
  2. 11.
  3. 13.
  4. 14.
  5. 17.

    Typical ORM ! that we DO NOT HAVE → Relying

    on mutable objects → Complex association model → Leaky abstractions → [ActiveRecord] tight coupling with database schema → [ActiveRecord] n+1 query problem → [ActiveRecord] callbacks → [ActiveRecord] huge API
  6. 29.

    Ease of use → Little code to write to get

    started → A lot of functionality OOTB → No boilerplate
  7. 46.
  8. 54.

    module Entities class User < ROM::Struct def first_name name.split(' ').first

    end def last_name name.split(' ').last end end end
  9. 55.

    module Entities class User < ROM::Struct def first_name name.split(' ').first

    end def last_name name.split(' ').last end end end
  10. 61.

    module Entities class User < ROM::Struct def has_tasks? !tasks.empty? end

    end end user = users.combine(:tasks).first user.has_tasks? # true
  11. 62.

    user = users.first user.has_tasks? # ROM::Struct::MissingAttribute: # undefined method `tasks'

    for # #<Entities::User id=1 name="Jane"> (attribute not loaded?)
  12. 64.

    → Dynamic query interface is maintained → Custom methods are

    maintained → Objects decoupled from the database are maintained too
  13. 69.
  14. 71.

    At any point in time, you can define structs with

    explicit attributes and ask rom-rb to load them
  15. 81.

    class Users < ROM::Relation[:sql] schema(infer: true) do associations do has_many

    :tasks, override: true, view: :for_users end end end class Tasks < ROM::Relation[:yaml] gateway :external schema(infer: true) def for_users(users) tasks.restrict(UserId: users.pluck(:id)) end end
  16. 82.

    class Users < ROM::Relation[:sql] schema(infer: true) do associations do has_many

    :tasks, override: true, view: :for_users end end end class Tasks < ROM::Relation[:yaml] gateway :external schema(infer: true) def for_users(users) tasks.restrict(UserId: users.pluck(:id)) end end
  17. 92.

    users. combine(:tasks). changeset(:create, name: "Joe", tasks: [{ title: "Task 1"

    }]). commit # => #<Entities::User id=4 name="Joe" tasks=[ # #<Entities::Task id=3 user_id=4 title="Task 1"> # ]>
  18. 94.

    class Users < ROM::Relation[:sql] schema(:SomehorriblyNamedUseRtable, as: :users) do attribute :UserIdentifier,

    Serial.meta(alias: :id) attribute :UserName, String.meta(alias: :name) end end users.first # #<ROM::Struct::User id=1, name="Jane">
  19. 96.

    class EncryptionMapper < ROM::Mapper register_as :encryption def call(relation) relation.map {

    |tuple| # do whatever you want } end end users.map_with(:encryption)
  20. 98.

    class NewUser < ROM::Changeset::Create map do rename_keys user_name: :name end

    end users.changeset(NewUser, user_name: "Jane").commit # #<ROM::Struct::User id=1 name="Jane">
  21. 102.
  22. 103.