„ActiveRecord“ ir „Ecto“, antra dalis

Tai yra antroji „ActiveRecord vs. Ecto“ serijos dalis, kurioje Betmenas ir Batgirlas kovoja dėl duomenų bazių užklausų ir mes lyginame obuolius ir apelsinus.

Išnagrinėjęs duomenų bazių schemas ir perkėlimus „ActiveRecord“ palyginti su „Ecto“ pirmąja dalimi, šiame įraše aprašoma, kaip „ActiveRecord“ ir „Ecto“ įgalina kūrėjus atlikti duomenų bazės užklausas ir kaip „ActiveRecord“ ir „Ecto“ lygina, kai susiduria su tais pačiais reikalavimais. Pakeliui taip pat išsiaiškinsime Batgirlo 1989–2011 m. Tapatybę.

Sėklos duomenys

Pradėkime! Remdamiesi duomenų bazės struktūra, apibrėžta pirmame šios serijos įraše, tarkime, kad vartotojai ir sąskaitų faktūrų lentelėse yra šie duomenys:

vartotojų

* „ActiveRecord“ sukurtas_atlaukas pagal nutylėjimą yra įterptas į „Ecto“.

sąskaitos faktūros

* „ActiveRecord“ sukurtas_atlaukas pagal nutylėjimą yra įterptas į „Ecto“.

Per šį įrašą atliktos užklausos daro prielaidą, kad aukščiau pateikti duomenys yra saugomi duomenų bazėje, todėl skaitydami ją turėkite omenyje šią informaciją.

Raskite elementą naudodami jo pagrindinį raktą

Pradėkime nuo įrašo iš duomenų bazės gavimo naudodamiesi pirminiu raktu.

„ActiveRecord“

irb (pagrindinis): 001: 0> User.find (1) Vartotojo apkrova (0,4 ms) PASIRINKITE „vartotojus“. * IŠ „vartotojų“ KUR „vartotojai“. „id“ = 1 USD RIBOTI 2 USD [[„id“, 1 ], [„LIMIT“, 1]] => # 

Ekto

iex (3)> Repo.get (vartotojas, 1)
[derinimo] QUERY OK šaltinis = „vartotojai“ db = 5,2 ms iššifruoti = 2,5 ms eilė = 0,1 ms
PASIRINKITE u0. „Id“, u0.
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
  el. paštas: „bette@kane.test“,
  vardas ir pavardė: „Bette Kane“,
  ID: 1,
  įterptas_at: ~ N [2018-01-01 10: 01: 00.000000],
  sąskaitos faktūros: # Ecto.Association.NotLoaded ,
  atnaujinta_at: ~ N [2018-01-01 10: 01: 00.000000]
}

Palyginimas

Abu atvejai yra gana panašūs. „ActiveRecord“ remiasi vartotojo modelio klasės radimo metodu. Tai reiškia, kad kiekviena „ActiveRecord“ vaikų klasė turi savo radimo metodą.

„Ecto“ naudoja kitokį požiūrį, remdamasis „Repository“ koncepcija kaip tarpininku tarp žemėlapių sudarymo sluoksnio ir srities. Naudodamas Ecto, vartotojo modulis neturi žinių, kaip atsidurti. Tokia atsakomybė yra „Repo“ modulyje, kuris sugeba susieti jį su duomenų aparatu, kuris mūsų atveju yra „Postgres“.

Palygindami pačią SQL užklausą, galime pastebėti keletą skirtumų:

  • „ActiveRecord“ įkelia visus laukus (vartotojus. *), O „Ecto“ - tik tuos laukus, kurie išvardyti schemos apibrėžime.
  • „ActiveRecord“ apima LIMIT 1 užklausai, o „Ecto“ - ne.

Gaunami visi elementai

Žengsime dar vieną žingsnį ir įkelkime visus vartotojus iš duomenų bazės.

„ActiveRecord“

irb (pagrindinis): 001: 0> „User.all“ vartotojo apkrova (0,5ms) PASIRINKITE „vartotojus“. * IŠ „vartotojų“ RIBOTI 1 USD [[„LIMIT“, 11]] => # , # , # , # ]>

Ekto

iex (4)> Repo.all (Vartotojas)
[derinimo] QUERY OK šaltinis = "vartotojai" db = 2,8 ms iššifruoti = 0,2 ms eilė = 0,2 ms
PASIRINKITE u0. "Id", u0. "Pilnas_vardas", u0. "El. Paštas", u0. "Įterptas_at", u0. "Atnaujintas_iš" iš "vartotojų" AS u0 []
[
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
    el. paštas: „bette@kane.test“,
    vardas ir pavardė: „Bette Kane“,
    ID: 1,
    įterptas_at: ~ N [2018-01-01 10: 01: 00.000000],
    sąskaitos faktūros: # Ecto.Association.NotLoaded ,
    atnaujinta_at: ~ N [2018-01-01 10: 01: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
    el. paštas: „barbara@gordon.test“,
    vardas ir pavardė: „Barbara Gordon“,
    id: 2,
    įterptas_at: ~ N [2018-01-02 10: 02: 00.000000],
    sąskaitos faktūros: # Ecto.Association.NotLoaded ,
    atnaujinta_at: ~ N [2018-01-02 10: 02: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
    el. paštas: „cassandra@cain.test“,
    „full_name“: „Cassandra Cain“,
    ID: 3,
    įdėta_at: ~ N [2018-01-03 10: 03: 00.000000],
    sąskaitos faktūros: # Ecto.Association.NotLoaded ,
    atnaujinta_bata: ~ N [2018-01-03 10: 03: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
    el. paštas: "stephanie@brown.test",
    „full_name“: „Stephanie Brown“,
    ID: 4,
    įterptas_at: ~ N [2018-01-04 10: 04: 00.000000],
    sąskaitos faktūros: # Ecto.Association.NotLoaded ,
    atnaujinta_ats .: ~ N [2018-01-04 10: 04: 00.000000]
  }
]

Palyginimas

Tai atitinka tą patį modelį, kaip ir ankstesniame skyriuje. „ActiveRecord“ naudoja visų klasių metodą, o „Ecto“, norėdama įkelti įrašus, remiasi saugyklos modeliu.

Vėl yra keletas SQL užklausų skirtumų:

Užklausa su sąlygomis

Labai mažai tikėtina, kad mums reikės surinkti visus įrašus iš lentelės. Bendras poreikis yra naudoti sąlygas grąžinamiems duomenims filtruoti.

Panaudosime šį pavyzdį, kad pateiktume visas sąskaitas, kurios vis dar turi būti apmokėtos (KUR sumokėta_NESUTEIKIAMA).

„ActiveRecord“

irb (pagrindinis): 024: 0> Invoice.where (paid_at: nil) Sąskaitų faktūrų apkrova (18,2ms) PASIRINKITE „sąskaitas faktūras“. * IŠ „sąskaitų“ Kur „sąskaitos faktūros“. , 11]] => # , # ]>

Ekto

iex (19)> kur (sąskaita faktūra, [i], is_nil (i.paid_at)) |> Repo.all ()
[derinimo] QUERY OK source = "sąskaitos faktūros" db = 20,2ms
PASIRINKITE i0. "Id", i0. "Mokėjimo_metodą", i0. "Sumokėtą_į", i0. "Vartotojo_idą", i0. "Įterptą_at", i0. "Atnaujintą_į" IŠ "iš sąskaitų-faktūrų" AS i0 WHERE "(i0." Sumokėta_at "yra NULL) []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    ID: 3,
    įterptas_at: ~ N [2018-01-04 08: 00: 00.000000],
    pay_at: nulis,
    mokėjimo metodas: nulis,
    atnaujinta_bata: ~ N [2018-01-04 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 3
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    ID: 4,
    įterptas_at: ~ N [2018-01-04 08: 00: 00.000000],
    pay_at: nulis,
    mokėjimo metodas: nulis,
    atnaujinta_bata: ~ N [2018-01-04 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 4
  }
]

Palyginimas

Abiejuose pavyzdžiuose naudojamas raktinis žodis, kuris yra ryšys su SQL WHERE išlyga. Nors generuojamos SQL užklausos yra gana panašios, tai, kaip ten patenka abi priemonės, turi keletą svarbių skirtumų.

„ActiveRecord“ automatiškai transformuoja „pay_at: nil“ argumentą į pay_at IS NULL SQL. Norėdami pasiekti tą patį išvestį naudodami „Ecto“, kūrėjai turi aiškiau išdėstyti savo ketinimus paskambinę is_nil ().

Kitas skirtumas, kurį reikia pabrėžti, yra „grynas“ funkcijos elgesys, kai Ecto. Paskambinus vien kur funkcija, jis nebendrauja su duomenų baze. Grįžimas kur funkcija yra „Ecto.Query“ struktūra:

iex (20)> kur (sąskaita faktūra, [i], is_nil (i.paid_at))
# Ecto.Query 

Duomenų bazė paliečiama tik tada, kai iškviečiama funkcija Repo.all (), kaip argumentą perduodant Ecto.Query struktūrą. Šis metodas leidžia sudaryti užklausą „Ecto“, kuri yra kito skyriaus tema.

Užklausos kompozicija

Vienas galingiausių duomenų bazės užklausų aspektų yra kompozicija. Tai apibūdina užklausą taip, kad joje būtų daugiau nei viena sąlyga.

Jei kuriate neapdorotas SQL užklausas, tai reiškia, kad tikriausiai naudosite kažkokį sujungimą. Įsivaizduokite, kad turite dvi sąlygas:

  1. not_paid = 'paid_at NE NULL'
  2. paid_with_paypal = 'payment_method = "Paypal"'

Jei norite sujungti šias dvi sąlygas naudojant neapdorotą SQL, tai reiškia, kad turėsite sujungti jas naudodami kažką panašaus į:

PASIRINKITE * IŠ Sąskaitų faktūrų, kur # {not_paid} IR # {paid_with_paypal}

Laimei, tiek „ActiveRecord“, tiek „Ecto“ turi tam sprendimą.

„ActiveRecord“

irb (pagrindinis): 003: 0> Invoice.where.not (paid_at: nil) .where (payment_method: "Paypal") Sąskaitų apkrova (8.0ms) PASIRINKITE "sąskaitos faktūros". * IŠ "sąskaitos faktūros" KUR "sąskaitos faktūros". " pay_at "NĖRA NEMOKAMAS IR" sąskaitos faktūros "." payment_method "= 1 USD RIBOTAS 2 USD [[" payment_method "," Paypal "], [" LIMIT ", 11]] => # ]>

Ekto

iex (6)> sąskaita faktūra |> kur ([i], o ne is_nil (i.paid_at)) |> kur ([i], i.payment_method == "Paypal") |> Repo.all ()
[derinimo] QUERY OK source = "sąskaitos faktūros" db = 30,0 ms dekoduoti = 0,6 ms eilės = 0,2 ms
PASIRINKITE i0. „Id“, i0. „Mokėjimo_metodas“, i0. "IS NULL)) IR ​​(i0." Pay_method "= 'Paypal') []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    id: 2,
    įterptas_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    mokėjimo_metodas: „Paypal“,
    atnaujinta_bata: ~ N [2018-01-03 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Palyginimas

Abi užklausos atsako į tą patį klausimą: „Kurios sąskaitos buvo apmokėtos ir kuriomis buvo naudojamasi„ Paypal “?“.

Kaip jau tikėtasi, „ActiveRecord“ siūlo glaustaus užklausos sudarymo būdą (tam pavyzdžiui), o „Ecto“ reikalauja, kad kūrėjai išleistų šiek tiek daugiau užklausos rašymo. Kaip įprasta, „Batgirl“ (našlaitis, nutildytas su „Cassandra Cain“ tapatybe) arba „Activerecord“ nėra tokie išsamūs.

Neapsigaukite dėl aukščiau pavaizduotos Ecto užklausos aiškumo ir akivaizdaus sudėtingumo. Realioje aplinkoje ši užklausa būtų perrašyta taip, kad atrodytų daugiau:

Sąskaita
|> kur ([i], o ne is_nil (i.paid_at))
|> kur ([i], i.payment_method == "Paypal")
|> Repo.all ()

Žiūrint iš šio kampo, „grynųjų“ funkcijos aspektų derinys, kai, pats nevykdantis duomenų bazės operacijų, su vamzdžio operatoriumi padaro užklausų kompoziciją „Ecto“ išties švarią.

Užsakymas

Užsakymas yra svarbus užklausos aspektas. Tai leidžia kūrėjams užtikrinti, kad pateiktas užklausos rezultatas atitiktų nurodytą užsakymą.

„ActiveRecord“

irb (pagrindinis): 002: 0> Invoice.order (sukurta_at:: desc) Sąskaitų apkrova (1,5 ms) PASIRINKITE „sąskaitas faktūras“. * IŠ „Sąskaitų faktūrų“ UŽSAKYKITE „Sąskaitos“. ", 11]] => # , # , # , # ]>

Ekto

iex (6)> order_by (sąskaita faktūra, aprašymas:: insert_at) |> Repo.all ()
[derinimo] QUERY OK source = "sąskaitos faktūros" db = 19.8ms
PASIRINKITE i0. "Id", i0. "Mokėjimo_metodą", i0. "Sumokėtą_į", i0. "Vartotojo_idą", i0. "Įterptą_į", i0. "Atnaujintą_į" IŠ "iš sąskaitos faktūros" AS i0 UŽSAKYTI I0. "Įdėtą_į" DESC " []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    ID: 3,
    įterptas_at: ~ N [2018-01-04 08: 00: 00.000000],
    pay_at: nulis,
    mokėjimo metodas: nulis,
    atnaujinta_bata: ~ N [2018-01-04 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 3
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    ID: 4,
    įterptas_at: ~ N [2018-01-04 08: 00: 00.000000],
    pay_at: nulis,
    mokėjimo metodas: nulis,
    atnaujinta_bata: ~ N [2018-01-04 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 4
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    id: 2,
    įterptas_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    mokėjimo_metodas: „Paypal“,
    atnaujinta_bata: ~ N [2018-01-03 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 2
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    ID: 1,
    įterptas_at: ~ N [2018-01-02 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    mokėjimo_metodas: „kreditinė kortelė“,
    atnaujinta_bata: ~ N [2018-01-02 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 1
  }
]

Palyginimas

Abiejuose įrankiuose tiesiai į priekį galima įtraukti užsakymą.

Nors „Ecto“ pavyzdyje kaip pirmasis parametras naudojama sąskaita faktūra, „order_by“ funkcija taip pat priima „Ecto.Query“ struktūrą, kuri įgalina „order_by“ funkciją naudoti kompozicijose, tokiose kaip:

Sąskaita
|> kur ([i], o ne is_nil (i.paid_at))
|> kur ([i], i.payment_method == "Paypal")
|> order_by (aprašymas:: insert_at)
|> Repo.all ()

Apriboti

Kokia būtų duomenų bazė be apribojimų? Nelaimė. Laimei, tiek „ActiveRecord“, tiek „Ecto“ padeda apriboti grąžinamų įrašų skaičių.

„ActiveRecord“

irb (pagrindinis): 004: 0> Invoice.limit (2)
Sąskaitų apkrova (0,2 ms) PASIRINKITE „sąskaitas faktūras“. * IŠ „Sąskaitų faktūrų“ LIMIT 1 USD [[„LIMIT“, 2]]
=> # , # ]>

Ekto

iex (22)> riba (sąskaita faktūra, 2) |> Repo.all ()
[derinimo] QUERY OK source = "sąskaitos faktūros" db = 3,6 ms
PASIRINKITE i0. "Id", i0. "Mokėjimo_metodą", i0. "Sumokėtą_į", i0. "Vartotojo_idą", i0. "Įterptą_į", i0. "Atnaujintą_į" iš "sąskaitų" AS "i0 LIMIT 2" []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    ID: 1,
    įterptas_at: ~ N [2018-01-02 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    mokėjimo_metodas: „kreditinė kortelė“,
    atnaujinta_bata: ~ N [2018-01-02 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 1
  },
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    id: 2,
    įterptas_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    mokėjimo_metodas: „Paypal“,
    atnaujinta_bata: ~ N [2018-01-03 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Palyginimas

Tiek „ActiveRecord“, tiek „Ecto“ turi būdą apriboti įrašų, pateiktų pagal užklausą, skaičių.

„Ecto“ limit veikia panašiai kaip „order_by“, todėl tinka užklausų kompozicijoms.

Asociacijos

„ActiveRecord“ ir „Ecto“ požiūriai į asociacijų tvarkymą skiriasi.

„ActiveRecord“

„ActiveRecord“ galite naudoti bet kokią modelyje apibrėžtą asociaciją, nereikia dėl to daryti nieko ypatingo, pavyzdžiui:

irb (pagrindinis): 012: 0> user = User.find (2) Vartotojo apkrova (0,3 ms) PASIRINKITE „vartotojus“. * IŠ „vartotojų“ KUR „vartotojai“. „id“ = 1 USD RIBOTI 2 USD [[„id“ , 2], [„LIMIT“, 1]] => #  irb (pagrindinis): 013: 0> user.invoices sąskaitos apkrova (0,4 ms) PASIRINKITE„ sąskaitos faktūros “. * IŠ„ sąskaitos faktūros “KUR„ sąskaitos faktūros “ . "user_id" = 1 USD LIMIT 2 USD [["user_id", 2], ["LIMIT", 11]] => # ] >

Aukščiau pateiktas pavyzdys rodo, kad paskambinę į user.invoices galime gauti vartotojo sąskaitų faktūrų sąrašą. Tai darydamas, „ActiveRecord“ automatiškai paklausė duomenų bazės ir įkeldavo su vartotoju susietas sąskaitas faktūras. Nors šis požiūris palengvina situaciją, nes reikia parašyti mažiau kodo ar nereikia jaudintis dėl papildomų žingsnių, tačiau tai gali sukelti problemų, jei kartojate kelis vartotojus ir gaunate kiekvieno vartotojo sąskaitas faktūras. Ši problema žinoma kaip „N + 1 problema“.

„ActiveRecord“ siūlomas „N + 1 problemos“ taisymas yra naudoti įtraukimo metodą:

irb (pagrindinis): 022: 0> vartotojas = Vartotojas.įeina (: sąskaitos faktūros) .find (2) Vartotojo apkrova (0,3 ms) PASIRINKITE „vartotojus“. * IŠ „vartotojų“ KUR „vartotojai“. „id“ = 1 USD RIBOS 2 USD [["id", 2], ["RIBOT", 1]] Sąskaitų apkrova (0,6 ms) PASIRINKITE "sąskaitas faktūras". * IŠ "Sąskaitų faktūrų" KUR "sąskaitos faktūros". "User_id" = 1 USD [["user_id", 2]] => #  irb (pagrindinis): 023: 0> user.invoices => # ]>

Tokiu atveju „ActiveRecord“ norėdamas įkelia sąskaitos faktūros susiejimą gaudamas vartotoją (kaip matyti iš dviejų parodytų SQL užklausų).

Ekto

Kaip jau galėjote pastebėti, Ecto tikrai nemėgsta nei magijos, nei netiesioginės. Reikia, kad kūrėjai aiškiai nurodytų savo ketinimus.

Pabandykime tą patį metodą naudodami „user.invoices“ su „Ecto“:

iex (7)> ​​user = Repo.get (User, 2)
[derinimo] QUERY OK šaltinis = „vartotojai“ db = 18,3 ms iššifruoti = 0,6 ms
PASIRINKITE u0. "Id", u0. "Pilną pavadinimą", u0. "El. Laišką", u0. "Įterpkite_at", u0. "Atnaujintą_iš" iš "vartotojų", kaip u0, kur (u0. "Id" = 1 USD) [2].
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
  el. paštas: „barbara@gordon.test“,
  vardas ir pavardė: „Barbara Gordon“,
  id: 2,
  įterptas_at: ~ N [2018-01-02 10: 02: 00.000000],
  sąskaitos faktūros: # Ecto.Association.NotLoaded ,
  atnaujinta_at: ~ N [2018-01-02 10: 02: 00.000000]
}
iex (8)> vartotojo sąskaitos faktūros
# Ecto.Association.NotLoaded 

Rezultatas yra Ecto.Association.NotLoaded. Ne tokia naudinga.

Norėdami prisijungti prie sąskaitų, kūrėjas turi pranešti apie tai Ecto, naudodamas išankstinio įkėlimo funkciją:

iex (12)> vartotojas = išankstinis įkėlimas (vartotojas,: sąskaitos faktūros) |> Repo.get (2)
[derinimo] QUERY OK source = "vartotojai" db = 11,8ms
PASIRINKITE u0. "Id", u0. "Pilną pavadinimą", u0. "El. Laišką", u0. "Įterpkite_at", u0. "Atnaujintą_iš" iš "vartotojų", kaip u0, kur (u0. "Id" = 1 USD) [2].
[derinimo] QUERY OK source = "sąskaitos faktūros" db = 4,2 ms
PASIRINKITE i0. "Id", i0. "Mokėjimo_metodą", i0. "Sumokėtą_į", i0. "Vartotojo_id", i0. "Įterptą_į", i0. "Atnaujintą_at", i0. "Vartotojo_id" IŠ "sąskaitos faktūros" AS i0 KUR ( i0. "user_id" = 1 USD) UŽSAKYTI i0. "user_id" [2]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: įkelta, „vartotojai“>,
  el. paštas: „barbara@gordon.test“,
  vardas ir pavardė: „Barbara Gordon“,
  id: 2,
  įterptas_at: ~ N [2018-01-02 10: 02: 00.000000],
  sąskaitos faktūros: [
    % Financex.Accounts.Invoice {
      __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
      id: 2,
      įterptas_at: ~ N [2018-01-03 08: 00: 00.000000],
      paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
      mokėjimo_metodas: „Paypal“,
      atnaujinta_bata: ~ N [2018-01-03 08: 00: 00.000000],
      vartotojas: # Ecto.Association.NotLoaded ,
      user_id: 2
    }
  ],
  atnaujinta_at: ~ N [2018-01-02 10: 02: 00.000000]
}

iex (15)> vartotojo sąskaitos faktūros
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: įkelta, „sąskaitos faktūros“>,
    id: 2,
    įterptas_at: ~ N [2018-01-03 08: 00: 00.000000],
    paid_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    mokėjimo_metodas: „Paypal“,
    atnaujinta_bata: ~ N [2018-01-03 08: 00: 00.000000],
    vartotojas: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Panašiai kaip „ActiveRecord“ apima, išankstinis įkėlimas pateikiant susijusias sąskaitas faktūras, kurios leis jas naudoti skambinant vartotojui.invoices.

Palyginimas

Vėlgi, kova tarp „ActiveRecord“ ir „Ecto“ baigiasi žinomu tašku: paaiškinimu. Abu įrankiai leidžia kūrėjams lengvai pasiekti asociacijas, tačiau nors „ActiveRecord“ daro jį mažiau aiškų, jo rezultatas gali būti netikėtas. „Ecto“ laikosi WYSIWYG tipo požiūrio, kuris daro tik tai, kas matoma kūrėjo apibrėžtoje užklausoje.

„Rails“ yra gerai žinomas kaip talpinimo strategijų naudojimas ir reklamavimas visuose skirtinguose programos sluoksniuose. Vienas iš pavyzdžių yra „rusiškos lėlės“ talpyklos laikymo metodo naudojimas, kuris savo burtų talpinimo mechanizmui visiškai pasikliauja „N + 1 problema“.

Patvirtinimai

Dauguma „ActiveRecord“ patvirtinimų taip pat pasiekiami „Ecto“. Čia pateiktas įprastų patvirtinimų sąrašas ir tai, kaip juos apibrėžia „ActiveRecord“ ir „Ecto“:

Apvyniokite

Jūs turite tai: pagrindinių obuolių ir apelsinų palyginimas.

„ActiveRecord“ orientuojasi į duomenų bazės užklausų atlikimo paprastumą. Didžioji jos funkcijų dalis yra sutelkta pačiose modelių klasėse, nereikalaujant iš kūrėjų, kad jie gerai suprastų duomenų bazę ar tokių operacijų poveikį. „ActiveRecord“ pagal nutylėjimą daro daug dalykų netiesiogiai. Nors tai leidžia lengviau pradėti, tai sunkiau suprasti, kas vyksta užkulisiuose, ir tai veikia tik tada, jei sekate „ActiveRecord kelią“.

Kita vertus, „Ecto“ reikalauja paaiškinimo, kurio rezultatas yra daugiau aiškus. Kaip privalumas viskas yra dėmesio centre, nieko nėra užkulisiuose ir jūs galite nurodyti savo kelią.

Priklausomai nuo jūsų požiūrio ir pasirinkimo, abu turi savo aukštyn kojomis. Taigi, palyginę obuolius ir apelsinus, mes pasiekiame šios GPGB ribas. Beveik pamiršau pasakyti „BatGirl“ kodinis vardas (1989–2001) buvo…. Orakulas. Tačiau nesigilinkime į tai.

Šį įrašą parašė svečių autorius Elvio Vicosa. Elvio yra knygos „Feniksas bėgių kūrėjams“ autorius.

Iš pradžių paskelbta tinklalapyje blog.appsignal.com 2018 m. Spalio 9 d.