ActiveRecord v primerjavi z Ecto, drugi del

To je drugi del serije "ActiveRecord vs. Ecto", v katerem se Batman in Batgirl borita nad poizvedovalnimi zbirkami podatkov in primerjamo jabolka in pomaranče.

Po pregledu shem baz podatkov in migracijah v prvem delu ActiveRecord proti Ecto, ta objava opisuje, kako tako ActiveRecord kot Ecto razvijalcem omogočata poizvedovanje po podatkovni bazi in kako se ActiveRecord in Ecto primerjata, če obravnavata iste zahteve. Ob poti bomo ugotovili tudi identiteto Batgirlove 1989–2011.

Podatki o semenu

Začnimo! Na podlagi strukture baze podatkov, opredeljene v prvi objavi te serije, predpostavimo, da imajo uporabniki in tabele računov v njih shranjene naslednje podatke:

uporabnikov

* Polje ustvari_at ActiveRecord je privzeto poimenovano vstavljeno_at v Ecto.

računi

* Polje ustvari_at ActiveRecord je privzeto poimenovano vstavljeno_at v Ecto.

Poizvedbe, opravljene prek te objave, predvidevajo, da so zgornji podatki shranjeni v bazi podatkov, zato upoštevajte te podatke, ko jih berete.

Poiščite element s primarnim ključem

Začnimo z pridobivanjem zapisov iz baze podatkov s primarnim ključem.

ActiveRecord

irb (glavna): 001: 0> User.find (1) Nalaganje uporabnikov (0,4 ms) IZBERITE "uporabnike". * OD "uporabnikov" KJE "uporabniki". "id" = $ 1 OMEJITEV $ 2 [["id", 1 ], ["LIMIT", 1]] => # 

Ecto

iex (3)> Repo.get (Uporabnik, 1)
[debug] QUERY OK source = "uporabniki" db = 5,2 ms dekodiranje = 2,5 ms čakalne vrste = 0,1 ms
IZBERI u0. "Id", u0. "Polno ime", u0. "Email", u0. "Vstavljeno_at", u0. "Posodobljeno_at" OD "uporabnikov" KOT u0 KJE (u0. "Id" = $ 1) [1]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
  email: "bette@kane.test",
  polno ime: "Bette Kane",
  id: 1,
  vstavljeno_at: ~ N [2018-01-01 10: 01: 00.000000],
  računi: # Ecto.Association.NotLoaded ,
  posodobljeno_at: ~ N [2018-01-01 10: 01: 00.000000]
}

Primerjava

Oba primera sta si precej podobna. ActiveRecord se opira na metodo iskanja razreda razreda Uporabniški model. To pomeni, da ima vsak otroški razred ActiveRecord svoj način iskanja.

Ecto uporablja drugačen pristop, pri čemer se zanaša na koncept Repository kot posrednik med plastjo preslikave in domeno. Pri uporabi Ecto Uporabniški modul nima znanja o tem, kako najti sebe. Takšna odgovornost je prisotna v modulu Repo, ki ga lahko preslika v spodnjo podatkovno shrambo, kar je v našem primeru Postgres.

Pri primerjavi same poizvedbe SQL lahko opazimo nekaj razlik:

  • ActiveRecord naloži vsa polja (uporabniki. *), Medtem ko Ecto naloži samo polja, navedena v definiciji sheme.
  • ActiveRecord vključuje poizvedbo LIMIT 1, Ecto pa ne.

Pridobivanje vseh elementov

Pojdimo še korak naprej in naložimo vse uporabnike iz baze podatkov.

ActiveRecord

irb (glavna): 001: 0> User.all Uporabniško nalaganje (0,5 ms) IZBERITE "uporabnike". * IZ "uporabnikov" OMEJA 1 USD [["LIMIT", 11]] => # , # , # , # ]>

Ecto

iex (4)> Repo.all (uporabnik)
[debug] QUERY OK source = "uporabniki" db = 2,8ms decode = 0,2ms čakalna vrsta = 0,2ms
IZBERI u0. "Id", u0. "Polno ime", u0. "Email", u0. "Vstavljeno_at", u0. "Posodobljeno_at" OD "uporabnikov" AS u0 []
[
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
    email: "bette@kane.test",
    polno ime: "Bette Kane",
    id: 1,
    vstavljeno_at: ~ N [2018-01-01 10: 01: 00.000000],
    računi: # Ecto.Association.NotLoaded ,
    posodobljeno_at: ~ N [2018-01-01 10: 01: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
    email: "barbara@gordon.test",
    polno ime: "Barbara Gordon",
    id: 2,
    vstavljeno_at: ~ N [2018-01-02 10: 02: 00.000000],
    računi: # Ecto.Association.NotLoaded ,
    posodobljeno_at: ~ N [2018-01-02 10: 02: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
    email: "cassandra@cain.test",
    polno ime: "Cassandra Cain",
    id: 3,
    vstavljeno_at: ~ N [2018-01-03 10: 03: 00.000000],
    računi: # Ecto.Association.NotLoaded ,
    posodobljeno_at: ~ N [2018-01-03 10: 03: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
    email: "stephanie@brown.test",
    polno ime: "Stephanie Brown",
    id: 4,
    vstavljeno_at: ~ N [2018-01-04 10: 04: 00.000000],
    računi: # Ecto.Association.NotLoaded ,
    posodobljeno_at: ~ N [2018-01-04 10: 04: 00.000000]
  }
]

Primerjava

Sledi popolnoma enakemu vzorcu kot prejšnji razdelek. ActiveRecord uporablja metodo vseh razredov in Ecto se za nalaganje zapisov zanaša na vzorec repozitorija.

V SQL poizvedbah je spet nekaj razlik:

Vprašanje s pogoji

Zelo malo je verjetno, da bomo morali pridobiti vse zapise iz tabele. Pogosta potreba je uporaba pogojev za filtriranje vrnjenih podatkov.

Uporabite ta primer za seznam vseh računov, ki jih je treba še plačati (KJE je plačano_at je NULL).

ActiveRecord

irb (glavna): 024: 0> Račun.od mesta (paid_at: nič) Nalaganje računa (18,2 ms) IZBERITE "račune". * IZ "računov" KJE "računi". "Pay_at" JE NULL LIMIT $ 1 [["LIMIT" , 11]] => # , # ]>

Ecto

iex (19)> kjer (Račun, [i], is_nil (i.paid_at)) |> Repo.all ()
[debug] QUERY OK source = "računi" db = 20,2 ms
IZBERITE i0. "Id", i0. "Plačilo_method", i0. "Plačan_at", i0. "Uporabniški_id", i0. "Vstavljen_at", i0. "Posodobljen_at" IZ računov "AS i0 KJE (i0." Plačan_at "JE NIČ) []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 3,
    vstavljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    paid_at: nič,
    plačilna metoda: nič,
    posodobljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 3
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 4,
    vstavljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    paid_at: nič,
    plačilna metoda: nič,
    posodobljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 4
  }
]

Primerjava

V obeh primerih je uporabljena ključna beseda kjer je povezava s klavzulo SQL WHERE. Čeprav so ustvarjene poizvedbe SQL precej podobne, ima način, kako oba orodja prideta, nekaj pomembnih razlik.

ActiveRecord samodejno pretvori argument pay_at: nil v stavek paid_at IS NULL SQL. Da bi prišli do istega izhoda z Ecto, morajo biti razvijalci bolj nazorni glede svoje namere, tako da pokličejo is_nil ().

Druga razlika, ki jo je treba poudariti, je "čisto" vedenje funkcije, kjer je v Ecto. Če kličete samo funkcijo kjer, ne vpliva na bazo podatkov. Vrnitev funkcije kjer je struktura Ecto.Query:

iex (20)> kje (račun, [i], is_nil (i.paid_at))
# Ecto.Query 

Baze podatkov se dotakne šele, ko se pokliče funkcija Repo.all (), ki strukturo Ecto.Query posreduje kot argument. Ta pristop omogoča sestavo poizvedb v Ecto, ki je predmet naslednjega razdelka.

Poizvedbena sestava

Eden najmočnejših vidikov poizvedb po bazah podatkov je sestava. Opisuje poizvedbo na način, ki vsebuje več kot en sam pogoj.

Če gradite neobdelane poizvedbe SQL, to pomeni, da boste verjetno uporabili kakšno povezavo. Predstavljajte si, da imate dva pogoja:

  1. not_paid = 'plača_at NI NULL'
  2. paid_with_paypal = 'Payment_method = "Paypal"'

Če želite kombinirati ta dva pogoja z uporabo surovega SQL, pomeni, da jih boste morali združiti z uporabo podobnega:

IZBERITE * IZ računov, KJE # {not_paid} IN # {paid_with_paypal}

Na srečo tako ActiveRecord kot Ecto imata rešitev za to.

ActiveRecord

irb (main): 003: 0> Račun.where.not (paid_at: nil) .where (Payment_method: "Paypal") Obremenitev računa (8,0ms) IZBERITE "račune". * IZ "računov", KJE "računi". " Pay_at "NI NULL IN" računi "." Payment_method "= $ 1 LIMIT $ 2 [[" Payment_method "," Paypal "], [" LIMIT ", 11]] => # ]>

Ecto

iex (6)> Račun |> kjer ([i], ne is_nil (i.paid_at)) |> kjer ([i], i.payment_method == "Paypal") |> Repo.all ()
[debug] QUERY OK source = "računi" db = 30,0ms decode = 0,6ms čakalna vrsta = 0,2ms
IZBERI i0. "Id", i0. "Plačilo_method", i0. "Plačan_at", i0. "Uporabniški_id", i0. "Vstavljen_at", i0. "Posodobljen_at" IZ "računov" AS i0 KJE (NE (i0. "Plača_at "JE NULL)) IN (i0." Payment_method "= 'Paypal') []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 2,
    vstavljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    Payment_method: "Paypal",
    posodobljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Primerjava

Obe poizvedbi odgovarjata na isto vprašanje: "Kateri računi so bili plačani in uporabljeni Paypal?".

Kot že pričakovano, ActiveRecord ponuja bolj jedrnat način sestavljanja poizvedbe (za ta primer), medtem ko Ecto od razvijalcev zahteva, da porabijo malo več za pisanje poizvedbe. Kot ponavadi Batgirl (sirota, nemna oseba z identiteto Cassandra Cain) ali Activerecord ni tako dobeseden.

Ne zavajajte se zaradi večbesednosti in navidezne zapletenosti zgoraj poizvedbe Ecto. V resničnem okolju bi bila ta poizvedba prepisana tako, da bi izgledala bolj kot:

Račun
|> kjer ([i], ne is_nil (i.paid_at))
|> kjer ([i], i.payment_method == "Paypal")
|> Repo.all ()

Če pogledamo iz tega zornega kota, kombinacija "čistih" vidikov funkcije, kjer, ki sama ne izvaja operacij baze podatkov, z operaterjem cevi, sestava poizvedb v Ectoju resnično čista.

Naročanje

Naročanje je pomemben vidik poizvedbe. Razvijalcem omogoča, da določeni rezultati poizvedb sledijo določenemu vrstnemu redu.

ActiveRecord

irb (glavna): 002: 0> Račun-račun (ustvarjeno_at:: desc) Nalaganje računa (1,5 ms) IZBERITE "račune". * IZ "računov" NAROČITE PO "računih". "ustvari_at" DESC LIMIT $ 1 [["LIMIT ", 11]] => # , # , # , # ]>

Ecto

iex (6)> order_by (Račun, opis:: vstavljen_at) |> Repo.all ()
[debug] QUERY OK source = "računi" db = 19,8 ms
IZBERI i0. "Id", i0. "Plačilo_method", i0. "Plačan_at", i0. "Uporabniški_id", i0. "Vstavljen_at", i0. "Posodobljen_at" IZ računov "AS i0 NAROČI PO i0." Vstavi_at "DESC []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 3,
    vstavljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    paid_at: nič,
    plačilna metoda: nič,
    posodobljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 3
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 4,
    vstavljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    paid_at: nič,
    plačilna metoda: nič,
    posodobljeno_at: ~ N [2018-01-04 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 4
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 2,
    vstavljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    Payment_method: "Paypal",
    posodobljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 2
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 1,
    vstavljeno_at: ~ N [2018-01-02 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    Payment_method: "Kreditna kartica",
    posodobljeno_at: ~ N [2018-01-02 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 1
  }
]

Primerjava

Dodajanje naročila poizvedbi je v obeh orodjih preprosto.

Čeprav primer Ecto kot račun uporablja prvi račun, funkcija order_by sprejema tudi strukture Ecto.Query, ki omogoča uporabo funkcije order_by v sestavkih, kot so:

Račun
|> kjer ([i], ne is_nil (i.paid_at))
|> kjer ([i], i.payment_method == "Paypal")
|> order_by (desc:: vstavljeno_at)
|> Repo.all ()

Omejevanje

Kaj bi bila baza podatkov brez omejitev? Katastrofa. Na srečo tako ActiveRecord kot Ecto pomagata omejiti število vrnjenih zapisov.

ActiveRecord

irb (glavni): 004: 0> Račun.limit (2)
Nalaganje računov (0,2 ms) IZBERITE "račune". * IZ "računov" OMEJITEV 1 USD [["OMEJITEV", 2]]
=> # , # ]>

Ecto

iex (22)> omejitev (račun, 2) |> Repo.all ()
[debug] QUERY OK source = "računi" db = 3,6 ms
IZBERI i0. "Id", i0. "Plačilo_method", i0. "Plačan_at", i0. "Uporabniški_id", i0. "Vstavljen_at", i0. "Posodobljen_at" IZ "računov" AS i0 LIMIT 2 []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 1,
    vstavljeno_at: ~ N [2018-01-02 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    Payment_method: "Kreditna kartica",
    posodobljeno_at: ~ N [2018-01-02 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 1
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 2,
    vstavljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    Payment_method: "Paypal",
    posodobljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Primerjava

ActiveRecord in Ecto omogočata omejitev števila zapisov, vrnjenih s poizvedbo.

Omejitev Ecto deluje podobno kot order_by in je primerna za sestave poizvedb.

Združenja

ActiveRecord in Ecto imata različen pristop, ko gre za ravnanje z združenji.

ActiveRecord

V ActiveRecordu lahko uporabite katero koli povezavo, določeno v modelu, ne da bi pri tem naredili kaj posebnega:

irb (glavna): 012: 0> uporabnik = User.find (2) Uporabniško nalaganje (0,3 ms) IZBERITE "uporabnike". * OD "uporabnikov" KJE "uporabniki". "id" = $ 1 OMEJITEV 2 $ [["id" , 2], ["LIMIT", 1]] => #  irb (glavni): 013: 0> uporabniški računi nalaganje računov (0,4 ms) IZBERITE" račune ". * IZ" računi ", KJE" računi " . "user_id" = $ 1 LIMIT $ 2 [["user_id", 2], ["LIMIT", 11]] => # ] >

Zgornji primer kaže, da lahko pri klicanju uporabniških računov dobimo seznam uporabniških računov. Pri tem je ActiveRecord samodejno poizvedoval po zbirki podatkov in naložil račune, povezane z uporabnikom. Medtem ko ta pristop olajša stvari, v smislu pisanja manj kode ali skrbi za dodatne korake, je lahko težava, če ponavljate več uporabnikov in prenašate račune za vsakega uporabnika. To vprašanje je znano kot "težava N + 1".

V ActiveRecordu je predlagana rešitev za "težavo N + 1" uporaba metode vključuje:

irb (main): 022: 0> user = User.includes (: računi) .find (2) User Load (0,3ms) IZBERI "uporabnike". * OD "users" KJE "uporabniki". "id" = $ 1 OMEJITEV $ 2 [["id", 2], ["OMEJITEV", 1]] Nalaganje računa (0,6 ms) IZBERITE "račune". * IZ "računov" KJE "računi". "User_id" = $ 1 [["user_id", 2]] => #  irb (glavna): 023: 0> user.invoices => # ]>

V tem primeru ActiveRecord pri pridobivanju uporabnika nestrpno naloži povezavo računov (kot je prikazano v dveh poizvedbah SQL).

Ecto

Kot ste morda že opazili, Ecto res ne mara magije ali implicitnosti. Od razvijalcev mora biti izrecno opredeljen o svojih namerah.

Poskusimo enak pristop z uporabniškimi računi z Ecto:

iex (7)> ​​uporabnik = Repo.get (Uporabnik, 2)
[debug] QUERY OK source = "uporabniki" db = 18,3ms decode = 0,6ms
IZBERI u0. "Id", u0. "Polno ime", u0. "Email", u0. "Vstavljeno_at", u0. "Posodobljeno_at" OD "uporabnikov" KOT u0 KJE (u0. "Id" = $ 1) [2]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
  email: "barbara@gordon.test",
  polno ime: "Barbara Gordon",
  id: 2,
  vstavljeno_at: ~ N [2018-01-02 10: 02: 00.000000],
  računi: # Ecto.Association.NotLoaded ,
  posodobljeno_at: ~ N [2018-01-02 10: 02: 00.000000]
}
iex (8)> uporabniški računi
# Ecto.Association.NotLoaded 

Rezultat je Ecto.Association.NotLoaded. Ni tako koristno.

Če želite imeti dostop do računov, mora razvijalec obvestiti Ecto o tem s funkcijo prednastavitve:

iex (12)> user = preload (Uporabnik,: računi) |> Repo.get (2)
[debug] QUERY OK source = "uporabniki" db = 11,8 ms
IZBERI u0. "Id", u0. "Polno ime", u0. "Email", u0. "Vstavljeno_at", u0. "Posodobljeno_at" OD "uporabnikov" KOT u0 KJE (u0. "Id" = $ 1) [2]
[debug] QUERY OK source = "računi" db = 4,2 ms
IZBERI i0. "Id", i0. "Plačilo_method", i0. "Plačan_at", i0. "Uporabniški_id", i0. "Vstavljen_at", i0. "Posodobljen_at", i0. "Uporabniški_ime" IZ "računov" AS i0 KJE ( i0. "user_id" = $ 1) NAROČI PO i0. "user_id" [2]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: naloženo, "uporabniki">,
  email: "barbara@gordon.test",
  polno ime: "Barbara Gordon",
  id: 2,
  vstavljeno_at: ~ N [2018-01-02 10: 02: 00.000000],
  računi: [
    % Financex.Accounts.Invoice {
      __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
      id: 2,
      vstavljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
      paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
      Payment_method: "Paypal",
      posodobljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
      uporabnik: # Ecto.Association.NotLoaded ,
      user_id: 2
    }
  ],
  posodobljeno_at: ~ N [2018-01-02 10: 02: 00.000000]
}

iex (15)> uporabniški računi
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: naloženo, "računi">,
    id: 2,
    vstavljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    Payment_method: "Paypal",
    posodobljeno_at: ~ N [2018-01-03 08: 00: 00.000000],
    uporabnik: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Podobno kot ActiveRecord vključuje, vnaprej naložite povezane račune, ki jim bodo na voljo pri klicanju uporabniških računov.

Primerjava

Ponovno se boj med ActiveRecordom in Ecto konča z eksplicitnostjo. Obe orodji razvijalcem omogočata preprost dostop do asociacij, a čeprav je ActiveRecord manj napak, je posledica tega lahko nepričakovano vedenje. Ecto upošteva način pristopa WYSIWYG, ki naredi samo tisto, kar je vidno v poizvedbi, ki jo je določil razvijalec.

Rails je dobro znan po uporabi in promociji strategij predpomnjenja v vseh različnih plasteh aplikacije. En primer je uporaba pristopa za predpomnjenje "ruske lutke", ki se za izvajanje svoje čarovnosti v celoti zanaša na težavo "N + 1".

Validacije

Večina potrditev v ActiveRecordu je na voljo tudi v Ecto. Tu je seznam pogostih potrditev in kako jih ActiveRecord in Ecto definirata:

Zaviti

Tu ga imate: primerjava med jabolki in pomarančami.

ActiveRecord se osredotoča na enostavnost izvajanja poizvedb po zbirki podatkov. Velika večina njegovih funkcij je osredotočena na same razrede modelov, od razvijalcev pa ni treba poglobljenega razumevanja baze podatkov niti vpliva takšnih operacij. ActiveRecord privzeto naredi implicitno veliko stvari. Čeprav je to lažje začeti, je težje razumeti, kaj se dogaja v zakulisju, in deluje le, če sledite načinu "ActiveRecord".

Po drugi strani Ecto zahteva izrecnost, ki ima za posledico več dobesedne kode. Kot korist je vse v središču pozornosti, nič zakulisno, in sami lahko določite svoj način.

Obe sta obrnjeni navzven, odvisno od vaše perspektive in želje. Torej, če primerjamo jabolka in pomaranče, prihajamo do konca tega BAT-tle-a. Skoraj pozabil sem vam povedati, da je bilo kodno ime BatGirl (1989–2001)…. Oracle. Toda ne gremo v to.

To objavo je napisal gostujoči avtor Elvio Vicosa. Elvio je avtor knjige Phoenix for Rails Developers.

Prvotno objavljeno na blog.appsignal.com 9. oktobra 2018.