ActiveRecord vs Ecto Pjesa e Dytë

Kjo është pjesa e dytë e serisë "ActiveRecord vs Ecto", në të cilën Batman dhe Batgirl luftojnë për të kërkuar bazën e të dhënave dhe ne krahasojmë mollët dhe portokallet.

Pasi të shikoni në skemat e bazës së të dhënave dhe migrimet në ActiveRecord vs Ecto pjesë e parë, ky post mbulon se si ActiveRecord dhe Ecto u mundësojnë zhvilluesve të kërkojnë bazën e të dhënave, dhe se si ActiveRecord dhe Ecto krahasohen kur merren me të njëjtat kërkesa. Gjatë rrugës, ne do të zbulojmë edhe identitetin e Batgirl 1989-1011.

Të dhënat e farës

Le të fillojmë! Bazuar në strukturën e bazës së të dhënave të përcaktuar në postimin e parë të kësaj serie, supozoni se përdoruesit dhe tabelat e faturave kanë të dhënat e mëposhtme të ruajtura në to:

përdoruesit

* Fusha e krijuar_at e ActiveRecord është emërtuar inserted_at në Ecto si parazgjedhje.

faturat

* Fusha e krijuar_at e ActiveRecord është emërtuar inserted_at në Ecto si parazgjedhje.

Pyetjet e kryera përmes këtij postimi supozojnë se të dhënat e mësipërme janë ruajtur në bazën e të dhënave, kështu që mbajini në mend këtë informacion gjatë leximit të tij.

Gjeni artikullin duke përdorur çelësin e tij parësor

Le të fillojmë me marrjen e një regjistrimi nga baza e të dhënave duke përdorur çelësin kryesor të tij.

ActiveRecord

irb (kryesore): 001: 0> User.find (1) Ngarkesa e përdoruesit (0.4ms) SELECT "përdorues". * "" Përdoruesit "KU KU" përdorues "." id "= 1 $ LIMIT $ 2 [[" id ", 1 ], ["LIMIT", 1]] => # 

Ecto

iex (3)> Repo.get (Përdoruesi, 1)
[debug] QUERY OK burim = "përdorues" db = 5.2ms deshifrim = radhë 2.5ms = 0.1ms
SELECT u0. "Id", u0. "Full_name", u0. "Email", u0. "Inserted_at", u0. "Used_at" user "FROM" AS u0 WHERE (u0. "Id" = $ 1) [1]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
  email: "bette@kane.test",
  full_name: "Bette Kane",
  id: 1,
  insert_at: ~ N [2018-01-01 10: 01: 00.000000],
  faturat: # Ecto.Association.NotLoaded ,
  azhurnuar_at: ~ N [2018-01-01 10: 01: 00.000000]
}

krahasim

Të dy rastet janë mjaft të ngjashme. ActiveRecord mbështetet në metodën e klasës së gjetjes së klasës së modelit të Përdoruesit. Do të thotë që çdo klasë e fëmijëve ActiveRecord ka metodën e vet të gjetjes në të.

Ecto përdor një qasje të ndryshme, duke u mbështetur në konceptin e Depo si ndërmjetës midis shtresës së hartës dhe domenit. Kur përdorni Ecto, Moduli i Përdoruesit nuk ka njohuri se si ta gjejë veten. Një përgjegjësi e tillë është e pranishme në modulin Repo, i cili është në gjendje ta hartë atë në nën bazën e të dhënave, që në rastin tonë është Postgres.

Kur krahasojmë vetë pyetjen SQL, mund të vërejmë disa ndryshime:

  • ActiveRecord ngarkon të gjitha fushat (përdoruesit. *), Ndërsa Ecto ngarkon vetëm fushat e listuara në përkufizimin e skemës.
  • ActiveRecord përfshin një KUFIZIM 1 për pyetjen, ndërsa Ecto jo.

Tërheqja e të gjitha sendeve

Le të shkojmë një hap më tej dhe të ngarkojmë të gjithë përdoruesit nga baza e të dhënave.

ActiveRecord

irb (kryesore): 001: 0> Përdoruesi.all Ngarkesa e përdoruesit (0.5ms) SHPEZIT "përdoruesit". * Përdoruesit "nga" LIMIT $ 1 [["" LIMIT ", 11]] => # , # , # , # ]>

Ecto

iex (4)> Repo.all (Përdorues)
[debug] QUERY OK burim = "përdorues" db = 2.8ms deshifroj = radhë 0.2ms = 0.2ms
SELECT u0. "Id", u0. "Full_name", u0. "Email", u0. "Inserted_at", u0. "Updated_at" përdoruesit "nga" përdoruesit "AS u0 []
[
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
    email: "bette@kane.test",
    full_name: "Bette Kane",
    id: 1,
    insert_at: ~ N [2018-01-01 10: 01: 00.000000],
    faturat: # Ecto.Association.NotLoaded ,
    azhurnuar_at: ~ N [2018-01-01 10: 01: 00.000000]
  }
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
    email: "barbara@gordon.test",
    full_name: "Barbara Gordon",
    id: 2,
    insert_at: ~ N [2018-01-02 10: 02: 00.000000],
    faturat: # Ecto.Association.NotLoaded ,
    azhurnuar_at: ~ N [2018-01-02 10: 02: 00.000000]
  }
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
    email: "cassandra@cain.test",
    full_name: "Cassandra Cain",
    id: 3,
    insert_at: ~ N [2018-01-03 10: 03: 00.000000],
    faturat: # Ecto.Association.NotLoaded ,
    azhurnuar_at: ~ N [2018-01-03 10: 03: 00.000000]
  }
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
    email: "stephanie@brown.test",
    full_name: "Stephanie Brown",
    id: 4,
    insert_at: ~ N [2018-01-04 10: 04: 00.000000],
    faturat: # Ecto.Association.NotLoaded ,
    azhurnuar_at: ~ N [2018-01-04 10: 04: 00.000000]
  }
]

krahasim

Ajo ndjek të njëjtën model të saktë si seksioni i mëparshëm. ActiveRecord përdor metodën e të gjitha klasave dhe Ecto mbështetet në modelin e depozitave për të ngarkuar rekordet.

Ekzistojnë përsëri disa dallime në pyetjet SQL:

Query me kushte

Shtë shumë e pamundur që duhet të marrim të gjitha regjistrimet nga një tabelë. Një nevojë e zakonshme është përdorimi i kushteve, për të filtruar të dhënat e kthyera.

Le ta përdorim atë shembull për të renditur të gjitha faturat që akoma duhet të paguhen (KU paguhen - është NULL).

ActiveRecord

irb (kryesore): 024: 0> Faturë.where (e paguar_at: nil) Ngarkesa e faturës (18.2ms) SHPENZUAR "faturat". * NGA "faturat" KU "faturat". , 11]] => # , # ]>

Ecto

iex (19)> ku (Faturë, [i], is_nil (i.paid_at)) |> Repo.all ()
[debug] QUERY OK burim = "fatura" db = 20.2ms
SELECT i0. "Id", i0. "Pagesa_method", i0. "Payment_at", i0. "User_id", i0. "Inserted_at", i0. "Updated_at" FROM "faturat" AS i0 WHERE (i0. "Used_at" IS I PAVLEFSHËM) []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 3,
    inserted_at: ~ N [2018-01-04 08: 00: 00.000000],
    paguar_at: nil,
    pagese_method: nil,
    azhurnuar_at: ~ N [2018-01-04 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 3
  }
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 4,
    inserted_at: ~ N [2018-01-04 08: 00: 00.000000],
    paguar_at: nil,
    pagese_method: nil,
    azhurnuar_at: ~ N [2018-01-04 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 4
  }
]

krahasim

Në të dy shembujt, fjalen ku përdoret fjala, e cila është një lidhje me klauzolën SQL WHERE. Megjithëse pyetjet e gjeneruara SQL janë mjaft të ngjashme, mënyra se si të dy mjetet mbërrijnë atje kanë disa ndryshime të rëndësishme.

ActiveRecord shndërron automatikisht argumentin e paguar_at: nil në deklaratën e paguar_ NUK është NULL SQL. Për të arritur në të njëjtën dalje duke përdorur Ecto, zhvilluesit duhet të jenë më të qartë për qëllimin e tyre, duke thirrur is_nil ().

Një tjetër ndryshim që duhet të theksohet është sjellja “e pastër” e funksionit ku ndodhet në Ecto. Kur thërret vetëm funksionin ku nuk funksionon, nuk ndërvepron me bazën e të dhënave. Kthimi i funksionit ku është një strukturë Ecto.Query:

iex (20)> ku (Faturë, [i], is_nil (i.paid_at))
# Ecto.Query 

Baza e të dhënave preket vetëm kur quhet funksioni Repo.all (), duke kaluar strukturën Ecto.Query si argument. Kjo qasje lejon përbërjen e pyetjeve në Ecto, e cila është objekt i seksionit tjetër.

Përbërja e pyetjes

Një nga aspektet më të fuqishme të pyetjeve të bazës së të dhënave është përbërja. Ai përshkruan një pyetje në një mënyrë që përmban më shumë se një kusht të vetëm.

Nëse po ndërtoni pyetje të papërpunuara SQL, do të thotë që ju do të përdorni një lloj bashkëpjesëmarrjeje. Imagjinoni që keni dy kushte:

  1. not_paid = 'paguar_at NUK është NULL'
  2. e paguar_with_paypal = 'pagesa_method = "Paypal"'

Për t'i kombinuar ato dy kushte duke përdorur SQL të papërpunuara, do të thotë që ju do të duhet t'i bashkoni ato duke përdorur diçka të ngjashme me:

SELECT * NGA faturat KU KU # {jo_ paguar} DHE # {paguar_with_paypal

Për fat të mirë, të dy ActiveRecord dhe Ecto kanë një zgjidhje për këtë.

ActiveRecord

irb (kryesore): 003: 0> Invoice.where.not (paguar_at: nil) .kudo (pagesa_method: "Paypal") Ngarkesa e Faturës (8.0ms) SELECT "fatura". * NGA "faturat" KU "faturat". " paguar_at "NUK është NULL DHE" fatura "." page_method "= $ 1 LIMIT $ 2 [[" "pagesa_method", "Paypal"], ["LIMIT", 11]] => # ]>

Ecto

iex (6)> Faturë |> ku ([i], jo is_nil (i.paid_at)) |> ku ([i], i.payment_method == "Paypal") |> Repo.all ()
[debug] QUERY OK burim = "fatura" db = 30.0ms deshifroj = 0.6ms radhë = 0.2ms
SELECT i0. "Id", i0. "Pagesa_method", i0. "Payment_at", i0. "User_id", i0. "Inserted_at", i0. "Updated_at" FROM "faturat" AS i0 WHERE (NOT (i0. "Paguar_at "NSHT N NULL)) DHE (i0." Pagesa_method "= 'Paypal') []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 2,
    inserted_at: ~ N [2018-01-03 08: 00: 00.000000],
    paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    pagesa: "Paypal",
    azhurnuar_at: ~ N [2018-01-03 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

krahasim

Të dy pyetjet po përgjigjen në të njëjtën pyetje: "Cilat fatura janë paguar dhe janë përdorur Paypal?".

Siç pritej tashmë, ActiveRecord ofron një mënyrë më të përmbledhur të kompozimit të pyetjes (për atë shembull), ndërsa Ecto kërkon që zhvilluesit të shpenzojnë pak më shumë për të shkruar pyetjen. Si zakonisht, Batgirl (Jetimi, memec një me identitetin e Cassandra Kain) ose Activerecord nuk është aq i folur.

Mos u mashtroni nga verbositeti dhe kompleksiteti i dukshëm i pyetjes Ecto të treguar më lart. Në një mjedis të vërtetë botëror, kjo pyetje do të rishkruhet të duket më shumë:

faturë
|> ku ([i], jo is_nil (i.paid_at))
|> ku ([i], i.payment_method == "Paypal")
|> Repo.all ()

Duke parë nga ai kënd, kombinimi i aspekteve "të pastra" të funksionit ku, i cili nuk kryen vetë operacione të bazës së të dhënave, me operatorin tub, e bën përbërjen e pyetjeve në Ecto me të vërtetë të pastër.

renditje

Renditja është një aspekt i rëndësishëm i një pyetjeje. Ai u mundëson zhvilluesve të sigurojnë që një rezultat i caktuar i pyetjes të ndjekë një rend të caktuar.

ActiveRecord

irb (kryesore): 002: 0> Faturë.order (krijuar_at:: desc) Ngarkesa e faturës (1.5ms) SELECT SELECT "fatura". * NGA "faturat" RRETH NGA "faturat". "krijuar_at" DESC LIMIT $ 1 [["LIMIT ", 11]] => # , # , # , # ]>

Ecto

iex (6)> rendi_by (Fatura, zbrit:: futur_at) |> Repo.all ()
[debug] QUERY OK burim = "fatura" db = 19.8ms
SELECT i0. "Id", i0. "Pagesa_method", i0. "Payment_at", i0. "User_id", i0. "Inserted_at", i0. "Updated_at" FROM "faturat" AS i0 ORDER BY i0. "Inserted_at" DESC []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 3,
    inserted_at: ~ N [2018-01-04 08: 00: 00.000000],
    paguar_at: nil,
    pagese_method: nil,
    azhurnuar_at: ~ N [2018-01-04 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 3
  }
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 4,
    inserted_at: ~ N [2018-01-04 08: 00: 00.000000],
    paguar_at: nil,
    pagese_method: nil,
    azhurnuar_at: ~ N [2018-01-04 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 4
  }
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 2,
    inserted_at: ~ N [2018-01-03 08: 00: 00.000000],
    paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    pagesa: "Paypal",
    azhurnuar_at: ~ N [2018-01-03 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 1,
    insert_at: ~ N [2018-01-02 08: 00: 00.000000],
    paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    pagesa: "Kartë krediti",
    azhurnuar_at: ~ N [2018-01-02 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 1
  }
]

krahasim

Shtimi i rendit në një pyetje është i drejtpërdrejtë në të dy mjetet.

Edhe pse shembulli Ecto përdor një Faturë si parametër të parë, funksioni rend_by pranon edhe strukturat Ecto.Query, gjë që mundëson që funksioni rendi_by të përdoret në kompozime, si:

faturë
|> ku ([i], jo is_nil (i.paid_at))
|> ku ([i], i.payment_method == "Paypal")
|> rendi_by (zbres:: futur_at)
|> Repo.all ()

Kufizimi

Cila do të ishte një bazë e të dhënave pa kufi? Një katastrofë. Për fat të mirë, të dy ActiveRecord dhe Ecto ndihmojnë për të kufizuar numrin e rekordeve të kthyera.

ActiveRecord

irb (kryesore): 004: 0> Faturë.limit (2)
Ngarkesa e faturës (0.2ms) SELECT SELECT "fatura". * NGA "faturat" LIMIT $ 1 [["" LIMIT ", 2]]
=> # , # ]>

Ecto

iex (22)> limit (Faturë, 2) |> Repo.all ()
[debug] QUERY OK burim = "fatura" db = 3.6ms
SELECT i0. "Id", i0. "Pagesa_method", i0. "Payment_at", i0. "User_id", i0. "Inserted_at", i0. "Updated_at" FROM "fatura" AS i0 LIMIT 2 []
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 1,
    insert_at: ~ N [2018-01-02 08: 00: 00.000000],
    paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    pagesa: "Kartë krediti",
    azhurnuar_at: ~ N [2018-01-02 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 1
  }
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 2,
    inserted_at: ~ N [2018-01-03 08: 00: 00.000000],
    paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    pagesa: "Paypal",
    azhurnuar_at: ~ N [2018-01-03 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

krahasim

Të dy ActiveRecord dhe Ecto kanë një mënyrë për të kufizuar numrin e regjistrave të kthyera nga një pyetje.

Kufiri i Ecto-ve funksionon ngjashëm me porosinë, duke qenë i përshtatshëm për kompozimet e pyetjeve.

shoqatat

ActiveRecord dhe Ecto kanë qasje të ndryshme kur bëhet fjalë për mënyrën e trajtimit të shoqatave.

ActiveRecord

Në ActiveRecord, ju mund të përdorni çdo shoqatë të përcaktuar në një model, pa pasur nevojë të bëni ndonjë gjë të veçantë për këtë, për shembull:

irb (kryesore): 012: 0> user = User.find (2) Ngarkesa e përdoruesit (0.3ms) SELECT "përdorues". * "" Përdoruesit "KU KU" përdorues "." id "= 1 $ LIMIT $ 2 [[" id " , 2], ["LIMIT", 1]] => #  irb (kryesore): 013: 0> user.invoices Ngarkesa e Faturës (0.4ms) SELECT" fatura ". SELECT". " . "user_id" = $ 1 LIMIT $ 2 [["user_id", 2], ["LIMIT", 11]] => # ] >

Shembulli i mësipërm tregon se ne mund të marrim një listë të faturave të përdoruesve kur telefononi user.invoices. Kur e bëni këtë, ActiveRecord automatikisht kërkoi në bazën e të dhënave dhe ngarkoi faturat që lidhen me përdoruesin. Ndërsa kjo qasje i bën gjërat më të lehta, në kuptimin e të shkruarit më pak kod ose duhet të shqetësoheni për hapa shtesë, mund të jetë problem nëse jeni duke përsëritur një numër të përdoruesve dhe duke tërhequr faturat për secilin përdorues. Kjo çështje njihet si problemi "N + 1".

Në ActiveRecord, zgjidhja e propozuar për "N + 1 problem" është të përdorni metodën e përfshirë:

irb (kryesore): 022: 0> user = User.includes (: fatura) .find (2) Ngarkesa e përdoruesit (0.3ms) SELECT "përdoruesit". $ 2 [["" ID ", 2], [" LIMIT ", 1]] Ngarkesa e faturës (0.6ms) SELECT" fatura ". 2]] => #  irb (kryesore): 023: 0> user.invoices => # ]>

Në këtë rast, ActiveRecord me padurim ngarkon shoqatën e faturave kur tërheq përdoruesin (siç shihet në dy pyetjet SQL të treguara).

Ecto

Siç mund ta keni vënë re tashmë, Ecto me të vërtetë nuk ju pëlqen magjia ose implikimi. Kërkon që zhvilluesit të jenë të qartë në lidhje me qëllimet e tyre.

Le të provojmë të njëjtën qasje të përdorimit të përdoruesve.invoices me Ecto:

iex (7)> ​​përdorues = Repo.get (Përdorues, 2)
[debug] QUERY OK burim = "përdorues" db = 18.3ms deshifroj = 0.6ms
SELECT u0. "Id", u0. "Full_name", u0. "Email", u0. "Inserted_at", u0. "Used_at" user "FROM" AS u0 WHERE (u0. "Id" = $ 1) [2]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
  email: "barbara@gordon.test",
  full_name: "Barbara Gordon",
  id: 2,
  insert_at: ~ N [2018-01-02 10: 02: 00.000000],
  faturat: # Ecto.Association.NotLoaded ,
  azhurnuar_at: ~ N [2018-01-02 10: 02: 00.000000]
}
iex (8)> user.invoices
# Ecto.Association.NotLoaded 

Rezultati është një Ecto.Association.NotLoaded. Jo aq i dobishëm.

Për të pasur akses në faturat, një zhvillues duhet ta njoftojë Ecto në lidhje me këtë, duke përdorur funksionin e para-ngarkesës:

iex (12)> user = preload (Përdoruesi,: faturat) |> Repo.get (2)
[debug] QUERY OK burim = "përdorues" db = 11.8ms
SELECT u0. "Id", u0. "Full_name", u0. "Email", u0. "Inserted_at", u0. "Used_at" user "FROM" AS u0 WHERE (u0. "Id" = $ 1) [2]
[debug] QUERY OK burim = "fatura" db = 4.2ms
SELECT i0. "Id", i0. "Pagesa_method", i0. "Payment_at", i0. "User_id", i0. "Inserted_at", i0. "Updated_at", i0. "User_id" FROM "faturon" AS i0 KU ( i0. "user_id" = $ 1) RRETH NGA i0. "user_id" [2]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: ngarkuar, "përdorues">,
  email: "barbara@gordon.test",
  full_name: "Barbara Gordon",
  id: 2,
  insert_at: ~ N [2018-01-02 10: 02: 00.000000],
  faturat: [
    % Financex.Accounts.Invoice {
      __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
      id: 2,
      inserted_at: ~ N [2018-01-03 08: 00: 00.000000],
      paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
      pagesa: "Paypal",
      azhurnuar_at: ~ N [2018-01-03 08: 00: 00.000000],
      përdoruesi: # Ecto.Association.NotLoaded ,
      user_id: 2
    }
  ],
  azhurnuar_at: ~ N [2018-01-02 10: 02: 00.000000]
}

iex (15)> user.invoices
[
  % Financex.Accounts.Invoice {
    __meta__: # Ecto.Schema.Metadata <: ngarkuar, "fatura">,
    id: 2,
    inserted_at: ~ N [2018-01-03 08: 00: 00.000000],
    paguar_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    pagesa: "Paypal",
    azhurnuar_at: ~ N [2018-01-03 08: 00: 00.000000],
    përdoruesi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Në mënyrë të ngjashme me ActiveRecord përfshin, para-ngarkesa me marr faturat e shoqëruara, të cilat do t'i bëjnë ato të disponueshme kur telefononi përdoruesin.invoices.

krahasim

Edhe një herë, beteja midis ActiveRecord dhe Ecto përfundon me një pikë të njohur: shpjegim. Të dy mjetet u lejojnë zhvilluesve të hyjnë lehtësisht në shoqata, por ndërsa ActiveRecord e bën atë më pak të folur, rezultati i tij mund të ketë sjellje të papritura. Ecto ndjek llojin e WYSIWYG të qasjes, e cila bën vetëm atë që shihet në pyetjen e përcaktuar nga zhvilluesi i saj.

Binarët janë të mirënjohur për përdorimin dhe promovimin e strategjive të caching në të gjitha shtresat e ndryshme të aplikacionit. Një shembull ka të bëjë me përdorimin e qasjes së caching "kukull ruse", e cila mbështetet tërësisht në "problemin N + 1" për mekanizmin e saj të mbajtjes së fshehtë për të kryer magjinë e tij.

Validations

Shumica e vlefshmërive të pranishme në ActiveRecord janë gjithashtu të disponueshme në Ecto. Këtu është një listë e vlefshmërive të zakonshme dhe se si ActiveRecord dhe Ecto i përcaktojnë ato:

Përfundoni

Aty e keni atë: mollët thelbësore përkundrejt krahasimit të portokallit.

ActiveRecord përqendrohet në lehtësinë e kryerjes së pyetjeve të bazës së të dhënave. Shumica e karakteristikave të saj janë përqendruar në klasat e modeleve vetë, duke mos kërkuar që zhvilluesit të kenë një kuptim të thellë të bazës së të dhënave, as ndikimin e operacioneve të tilla. ActiveRecord bën shumë gjëra në mënyrë implicite nga parazgjedhja. Edhe pse kjo e bën më të lehtë fillimin, e bën më të vështirë të kuptoni se çfarë po ndodh pas skenave dhe funksionon vetëm nëse ndiqni "mënyrën ActiveRecord".

Ecto, nga ana tjetër, kërkon shpjegim i cili rezulton në më shumë kod verbose. Si përfitim, gjithçka është në qendër të vëmendjes, asgjë prapa skenave dhe ju mund të specifikoni mënyrën tuaj.

Të dy kanë anën e tyre në varësi të perspektivës dhe preferencës suaj. Pra, duke krahasuar mollët dhe portokallet, ne i arrijmë fundit të kësaj BAT-tle. Pothuajse harrova të të them emrin e koduar të BatGirl (1989–2001) ishte…. Oracle. Por le të mos hyjmë në atë.

Ky postim është shkruar nga autori mysafir Elvio Vicosa. Elvio është autori i librit Phoenix for Rails Developers.

Botuar fillimisht në blog.appsignal.com më 9 tetor 2018.