Version 4.0

Core » Commands

Commands are used to make changes in your data. Every adapter provides its own command specializations, that can use database-specific features.

Core commands include following types:

  • :create - a command which inserts new tuples
  • :update - a command which updates existing tuples
  • :delete - a command which deletes existing tuples

Working with commands

You can get a command object via Relation#command interface. All core command types are supported by this method.

Assuming you have a users relation available:

:create command example

# inserting a single tuple
create_user = users.command(:create) "Jane")

# inserting a multiple tuples
create_user = users.command(:create, result: :many)[{ name: "Jane" }, { name: "John" }])

:update command example

update_user = users.by_pk(1).command(:update) "Jane Doe")

:delete command example

delete_user = users.by_pk(1).command(:delete)

Using custom command types

You can define custom command types too. This is useful when the logic is complex and you prefer to encapsulate it in a single class.

class MyCommand < ROM::SQL::Commands::Create
  relation :users
  register_as :my_command

  def execute(tuple)
    # do whatever you need

When your command is available in the configured rom container, you can get it in the standard way:

my_command = users.command(:my_command) "Jane")

Commands vs Changesets

Commands are the underlying abstraction for making changes in your database, whereas changesets should be treated as a more advanced abstraction, which provides additional data mapping functionality, and support for associating data.

For consistency, you should consider using changesets instead of commands; however, if you're processing larger amounts of data, and performance is a concern, you may want to use commands instead.

Here are benchmarks showing you roughly performance difference between the two:

=> benchmark: create command vs changeset

Warming up --------------------------------------
             command   226.000  i/100ms
           changeset   152.000  i/100ms
Calculating -------------------------------------
             command      2.238k (±10.5%) i/s -     11.300k in   5.134520s
           changeset      1.416k (±17.1%) i/s -      6.840k in   5.035512s

             command:     2237.6 i/s
           changeset:     1415.6 i/s - 1.58x  slower

=> benchmark: update command vs changeset

Warming up --------------------------------------
             command    35.000  i/100ms
           changeset    21.000  i/100ms
Calculating -------------------------------------
             command    405.284  (± 3.5%) i/s -      2.030k in   5.014935s
           changeset    213.359  (± 4.2%) i/s -      1.071k in   5.028808s

             command:      405.3 i/s
           changeset:      213.4 i/s - 1.90x  slower

=> benchmark: delete command vs changeset

Warming up --------------------------------------
             command   230.000  i/100ms
           changeset   134.000  i/100ms
Calculating -------------------------------------
             command      2.280k (± 5.0%) i/s -     11.500k in   5.057193s
           changeset      1.452k (±14.9%) i/s -      7.102k in   5.044861s

             command:     2280.2 i/s
           changeset:     1451.5 i/s - 1.57x  slower