Ecto Ikkinchi qismi. ActiveRecord va boshqalar

Bu "ActiveRecord vs. Ecto" seriyasining ikkinchi qismi, unda Batman va Batgirl ma'lumotlar bazalarini so'rash uchun kurashadilar va biz olma va apelsinlarni taqqoslaymiz.

ActiveRecord va Ecto birinchi qismidagi ma'lumotlar bazasi sxemalari va migratsiyalarini ko'rib chiqqandan so'ng, ushbu xabar ActiveRecord va Ecto dasturchilariga ma'lumotlar bazasini so'rashga imkon berishini va bir xil talablarni bajarishda ActiveRecord va Ecto ikkalasini taqqoslashni o'z ichiga oladi. Yo'l davomida, biz shuningdek, Batgirlning 1989–2011 shaxsini bilib olamiz.

Urug' haqida ma'lumot

Qani boshladik! Ushbu ketma-ket birinchi xabarda belgilangan ma'lumotlar bazasi tuzilishiga asoslanib, foydalanuvchilar va schyot-fakturalar jadvallarida quyidagi ma'lumotlar saqlangan deb taxmin qiling.

foydalanuvchilar

* ActiveRecord tomonidan yaratilgan_at maydoni sukut bo'yicha Ecto-ga kiritilgan_at deb nomlangan.

hisob-fakturalar

* ActiveRecord tomonidan yaratilgan_at maydoni sukut bo'yicha Ecto-ga kiritilgan_at deb nomlangan.

Ushbu xabar orqali amalga oshirilgan so'rovlar yuqoridagi ma'lumotlar bazada saqlangan deb taxmin qiladi, shuning uchun uni o'qiyotganda ushbu ma'lumotni yodda tuting.

Asosiy kalit yordamida elementni toping

Dastlabki kalitdan foydalanib ma'lumotlar bazasidan yozuv olishni boshlaylik.

ActiveRecord

irb (asosiy): 001: 0> User.find (1) Foydalanuvchi yuklamasi (0.4msm) "foydalanuvchilar" TANLASH. * "foydalanuvchilar" QAYERDAN "foydalanuvchilar" dan. "id" = $ 1 LIMIT $ 2 [["id", 1 ], ["LIMIT", 1]] => # 

Ekto

iex (3)> Repo.get (Foydalanuvchi, 1)
[nosozlik] QUERY OK manba = "foydalanuvchilar" db = 5.2ms dekod = 2,5ms navbat = 0,1ms
"ID", u0. "To'liq ism", u0. "Elektron pochta", u0. "Kiritilgan_at", u0. "Yangilangan" "foydalanuvchilar" dan "qaerda bo'lsa, u0" "id" = $ 1) [1]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
  elektron pochta: "bette@kane.test",
  to'liq nomi: "Bette Kane",
  id: 1,
  kiritilgan_at: ~ N [2018-01-01 10: 01: 00.000000],
  hisob-fakturalar: # Ecto.Association.NotLoaded ,
  yangilangan_at: ~ N [2018-01-01 10: 01: 00.000000]
}

Taqqoslash

Ikkala holat ham bir-biriga o'xshash. ActiveRecord foydalanuvchi modeli klassining topish klassi usuliga tayanadi. Bu shuni anglatadiki, har bir ActiveRecord bolalar sinfida o'ziga xos topish usuli mavjud.

Ecto xaritalar qatlami va domen o'rtasida vositachi sifatida Repository tushunchasiga tayanib, boshqa yondashuvdan foydalanadi. Ecto-dan foydalanganda, foydalanuvchi moduli o'zini qanday topish haqida ma'lumotga ega emas. Bunday javobgarlik Repo modulida mavjud bo'lib, uni bizning ma'lumotimiz ostidagi ma'lumotlar omboriga joylashtirishi mumkin, bu bizning holatlarimiz Postgres.

SQL so'rovni o'zi bilan taqqoslashda biz bir nechta farqlarni aniqlashimiz mumkin:

  • ActiveRecord barcha maydonlarni (foydalanuvchilar. *) Yuklaydi, Ecto esa faqat sxemani aniqlashda keltirilgan maydonlarni yuklaydi.
  • ActiveRecord so'rov uchun LIMIT 1 ni o'z ichiga oladi, Ecto esa yo'q.

Barcha elementlar yuklanmoqda

Keling, bir qadam tashlaymiz va barcha foydalanuvchilarni ma'lumotlar bazasidan yuklaymiz.

ActiveRecord

irb (asosiy): 001: 0> User.all foydalanuvchi yuki (0,5 ms) "foydalanuvchilar" ni tanlang. * "foydalanuvchilar" dan LIMIT $ 1 [["LIMIT", 11]] => # , # , # , # ]>

Ekto

iex (4)> Repo.all (Foydalanuvchi)
[nosozlik] QUERY OK manba = "foydalanuvchilar" db = 2.8ms dekod = 0.2m navbat = 0,2ms
"ID", u0. "To'liq ism", u0. "Elektron pochta", u0. "Kiritilgan_at", u0. "Yangilangan" "foydalanuvchilar" AS u0 []
[
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
    elektron pochta: "bette@kane.test",
    to'liq nomi: "Bette Kane",
    id: 1,
    kiritilgan_at: ~ N [2018-01-01 10: 01: 00.000000],
    hisob-fakturalar: # Ecto.Association.NotLoaded ,
    yangilangan_at: ~ N [2018-01-01 10: 01: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
    elektron pochta: "barbara@gordon.test",
    to'liq nomi: "Barbara Gordon",
    id: 2,
    kiritilgan_at: ~ N [2018-01-02 10: 02: 00.000000],
    hisob-fakturalar: # Ecto.Association.NotLoaded ,
    yangilangan_at: ~ N [2018-01-02 10: 02: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
    elektron pochta: "cassandra@cain.test",
    to'liq ism: "Cassandra Cain",
    id: 3,
    kiritilgan_at: ~ N [2018-01-03 10: 03: 00.000000],
    hisob-fakturalar: # Ecto.Association.NotLoaded ,
    yangilangan_at: ~ N [2018-01-03 10: 03: 00.000000]
  },
  % Financex.Accounts.User {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
    elektron pochta: "stephanie@brown.test",
    to'liq nomi: "Stefani Braun",
    id: 4,
    kiritilgan_at: ~ N [2018-01-04 10: 04: 00.000000],
    hisob-fakturalar: # Ecto.Association.NotLoaded ,
    yangilangan_at: ~ N [2018-01-04 10: 04: 00.000000]
  }
]

Taqqoslash

Bu oldingi qism bilan bir xil naqshga amal qiladi. ActiveRecord barcha klass usulidan foydalanadi va Ecto yozuvlarni yuklash uchun omborga tayanadi.

SQL so'rovlarida yana bir qator farqlar mavjud:

Shartlar bilan so'rash

Jadvaldan barcha yozuvlarni olish kerakligi dargumon. Qaytarilgan ma'lumotlarni filtrlash uchun shartlardan foydalanish odatiy ehtiyojdir.

Keling, to'lanishi kerak bo'lgan barcha schyot-fakturalarni ro'yxatlash uchun ushbu misoldan foydalanaylik (BU YERDA to'langan_ NULL).

ActiveRecord

naushnik (asosiy): 024: 0> Hisob-faktura joylashadigan joy (pullik_at: nol) Hisob-faktura yuki (18.2msm) "hisob-fakturalarni" TANLASH. * FROM "fakturalar" "faktura" Qaerda "faktura". "to'langan_at" NULL LIMIT $ 1 [["LIMIT"] , 11]] => # ]>

Ekto

iex (19)> qaerda (Hisob-faktura, [i], is_nil (i.paid_at)) |> Repo.all ()
[debug] QUERY OK manba = "fakturalar" db = 20.2ms
"ID", i0. "To'lov_metxod", i0. "To'langan_at", i0. "Foydalanuvchi_id", i0. "Kiritilgan_at", i0. "Yangilangan_at" FROM "Xarajatlarni" i0 qaerda ekanligi (i0. "Pulli_at") NULL) []
[
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 3,
    kiritilgan_at: ~ N [2018-01-04 08: 00: 00.000000],
    to'langan_at: nol,
    to'lov_metod: nol,
    yangilangan_at: ~ N [2018-01-04 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 3
  },
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 4,
    kiritilgan_at: ~ N [2018-01-04 08: 00: 00.000000],
    to'langan_at: nol,
    to'lov_metod: nol,
    yangilangan_at: ~ N [2018-01-04 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 4
  }
]

Taqqoslash

Ikkala misolda ham SQL WHERE gapiga ulanish uchun kalit so'z ishlatiladi. Yaratilgan SQL so'rovlari bir-biriga o'xshash bo'lsa-da, ikkala vositaning qanday erishishi ham muhim farqlarga ega.

ActiveRecord pulli_at: nol argumentni avtomatik ravishda IS_ NULL SQL bayonotiga o'zgartiradi. Ecto-dan foydalangan holda bir xil natijaga erishish uchun, ishlab chiqaruvchilar is_nil () ni chaqirib, o'zlarining maqsadlari to'g'risida aniqroq bo'lishlari kerak.

Ta'kidlash kerak bo'lgan yana bir farq bu funktsiyaning "sof" harakati, bu erda Ecto. Qaerda joylashgan funktsiyani chaqirganda, u ma'lumotlar bazasi bilan o'zaro ta'sir qilmaydi. Qayerda funksiya Ecto.Query strukturasi:

iex (20)> qaerda (Hisob-faktura, [i], is_nil (i.paid_at))
# Ecto.Query 

Ma'lumotlar bazasi faqat Repo.all () funktsiyasi chaqirilganda, Ecto.Query tizimini argument sifatida uzatganda tegib turadi. Ushbu yondashuv keyingi qismning mavzusi bo'lgan Ecto-da so'rovlar tarkibini yaratishga imkon beradi.

So'rov tarkibi

Ma'lumotlar bazasi so'rovlarining eng kuchli jihatlaridan biri bu kompozitsiyadir. U bir nechta shartlarni o'z ichiga olgan tarzda so'rovni tavsiflaydi.

Agar siz SQL xom-ashyolarini yaratayotgan bo'lsangiz, demak, siz qandaydir ulanishlarni ishlatasiz. Tasavvur qiling, sizda ikkita shart bor:

  1. not_paid = 'to'langan pul NULL EMAS'
  2. pull_with_paypal = 'to'lov_method = "Paypal"'

SQL xom ashyosidan foydalangan holda ushbu ikki holatni birlashtirish uchun, siz shunga o'xshash narsani ishlatib, ularni bog'lashingiz kerak bo'ladi:

TANLANG * FROM fakturalar Qaerda # {to'lanmagan} va # {to'langan_vaqida_paypal}

Yaxshiyamki, ActiveRecord ham, Ecto ham buning echimiga ega.

ActiveRecord

naushnik (asosiy): 003: 0> Hisob-faktura.joy.not (to'langan_at: nol) .bu erda (to'lov_metod: "Paypal") Hisob-faktura yuklamasi (8.0ms) "hisob-fakturalarni" SELECT. "FROM" schyot-fakturalari "Qaerda" fakturalar "". " to'langan_at "YO'Q emas" va "fakturalar" emas. "to'lov_method" = $ 1 LIMIT $ 2 [["to'lov_metod", "Paypal"], ["LIMIT", 11]] => # ]>

Ekto

iex (6)> Hisob-faktura |> qaerda ([i], not_nil (i.paid_at)) |> qaerda ([i], i.payment_method == "Paypal") |> Repo.all ()
[nosozlik] QUERY OK manba = "hisob-fakturalar" db = 30.0ms dekod = 0.6ms navbat = 0,2ms
I0. "Id", i0. "To'lov_method", i0. "To'langan_at", i0. "Foydalanuvchi_id", i0. "Kiritilgan_at", i0. "Yangilangan_at" FROM "Xarajatlarni" i0 qaerda (EMAS (i0. "Pullik") "NULL") va AND (i0. "Payment_method" = 'Paypal') []
[
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 2,
    kiritilgan_at: ~ N [2018-01-03 08: 00: 00.000000],
    pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    to'lov_metod: "Paypal",
    yangilangan_at: ~ N [2018-01-03 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Taqqoslash

Ikkala so'rov ham bir xil savolga javob bermoqda: "Qaysi hisob-fakturalar to'langan va Paypal ishlatilgan?".

Kutilganidek, ActiveRecord so'rovni tuzishning yanada aniq usulini taklif qiladi (masalan, misol uchun), Ecto esa dasturchilar so'rovni yozishga biroz ko'proq pul sarflashni talab qiladi. Odatdagidek, Batgirl (Cassandra Cain identifikatori bilan soqov bo'lgan etim) yoki Activerecord og'zaki emas.

Yuqorida ko'rsatilgan Ecto so'rovining so'zlar va aniqligi bilan aldanmang. Haqiqiy dunyo sharoitida ushbu so'rov yana o'xshash ko'rinishda qayta yoziladi:

Hisob-faktura
|> qaerda ([i], not_nil emas (i.paid_at))
|> qaerda ([i], i.payment_method == "Paypal")
|> Repo.all ()

Ushbu nuqtai nazardan qaraganda, funktsiyaning "sof" tomonlari kombinatsiyasi, bu erda ma'lumotlar bazasini o'zi bajarmaydigan, quvur operatori yordamida Ecto-da so'rovlar tarkibi haqiqatan ham toza bo'ladi.

Buyurtma berish

Buyurtma so'rovning muhim qismidir. Dasturchilarga berilgan so'rov natijalarining belgilangan tartibda bajarilishini ta'minlashga imkon beradi.

ActiveRecord

dazmol (asosiy): 002: 0> Hisob-faktura yuklamasi (yaratilgan_at:: tushirish) Hisob-faktura yuki (1.5sm) "hisob-fakturalarni" SELECT. * "fakturalar" dan FROM "fakturalar" bo'yicha buyurtma. "yaratilgan_at" DESC LIMIT $ 1 [["" LIMIT) ", 11]] => # , # , # , # ]>

Ekto

iex (6)> order_by (Hisob-faktura, tushirish:: kiritilgan_at) |> Repo.all ()
[debug] QUERY OK manba = "fakturalar" db = 19.8ms
"ID", i0. "To'lov_method", i0. "To'langan_at", i0. "Foydalanuvchi_id", i0. "Kiritilgan_at", i0. "Yangilangan_at" FROM "schyot-fakturalari" i0 buyrug'i bilan "i0." Kiritilgan_at "DESC" []
[
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 3,
    kiritilgan_at: ~ N [2018-01-04 08: 00: 00.000000],
    to'langan_at: nol,
    to'lov_metod: nol,
    yangilangan_at: ~ N [2018-01-04 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 3
  },
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 4,
    kiritilgan_at: ~ N [2018-01-04 08: 00: 00.000000],
    to'langan_at: nol,
    to'lov_metod: nol,
    yangilangan_at: ~ N [2018-01-04 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 4
  },
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 2,
    kiritilgan_at: ~ N [2018-01-03 08: 00: 00.000000],
    pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    to'lov_metod: "Paypal",
    yangilangan_at: ~ N [2018-01-03 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 2
  },
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 1,
    kiritilgan_at: ~ N [2018-01-02 08: 00: 00.000000],
    pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    to'lov_metod: "Kredit karta",
    yangilangan_at: ~ N [2018-01-02 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 1
  }
]

Taqqoslash

So'rovga buyurtma qo'shish ikkala vositada ham oldinga siljiydi.

Ecto misolida birinchi faktura sifatida fakturadan foydalanilgan bo'lsa-da, order_by funktsiyasi Ecto.Query tarkibini ham qabul qiladi, bu order_by funktsiyasini kompozitsiyalarda ishlatishga imkon beradi:

Hisob-faktura
|> qaerda ([i], not_nil emas (i.paid_at))
|> qaerda ([i], i.payment_method == "Paypal")
|> order_by (tushirish:: kiritilgan_at)
|> Repo.all ()

Cheklov

Cheklanmagan ma'lumotlar bazasi nima bo'lishi kerak? Falokat. Yaxshiyamki, ActiveRecord ham, Ecto ham qaytarilgan yozuvlar sonini cheklashga yordam beradi.

ActiveRecord

g'altak (asosiy): 004: 0> Faktura.limit (2)
Hisob-faktura yuki (0,2 m) "hisob-fakturalarni" SELECT. * FROM "fakturalar" LIMIT $ 1 [["" LIMIT ", 2]]
=> # , # ]>

Ekto

iex (22)> cheklash (Hisob-faktura, 2) |> Repo.all ()
[debug] QUERY OK manbai = "fakturalar" db = 3.6ms
SELECT i0. "Id", i0. "Payment_method", i0. "Pull_at", i0. "User_id", i0. "Added_at", i0. "Updated_at" FROM "faktura" AS i0 LIMIT 2 []
[
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 1,
    kiritilgan_at: ~ N [2018-01-02 08: 00: 00.000000],
    pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    to'lov_metod: "Kredit karta",
    yangilangan_at: ~ N [2018-01-02 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 1
  },
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 2,
    kiritilgan_at: ~ N [2018-01-03 08: 00: 00.000000],
    pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    to'lov_metod: "Paypal",
    yangilangan_at: ~ N [2018-01-03 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

Taqqoslash

ActiveRecord ham, Ecto ham so'rov orqali qaytarilgan yozuvlar sonini cheklash usuliga ega.

Ecto-ning chegarasi buyurtma_by-ga o'xshash tarzda ishlaydi, so'rov kompozitsiyalariga mos keladi.

Uyushmalar

Assotsiatsiyalarga qanday munosabatda bo'lish haqida gap ketganda, ActiveRecord va Ecto turli xil yondashuvga ega.

ActiveRecord

ActiveRecord-da siz biron bir alohida biron bir narsani qilmasdan, modelda aniqlangan har qanday aloqani ishlatishingiz mumkin, masalan:

irb (asosiy): 012: 0> foydalanuvchi = User.find (2) Foydalanuvchi yuki (0.3msm) "foydalanuvchilar" TANLASH. * "foydalanuvchilar" QAYERDAN "foydalanuvchilar" dan. "id" = $ 1 LIMIT $ 2 [["id" , 2], ["LIMIT", 1]] => #  naushnik (asosiy): 013: 0> user.invoices Hisob-faktura yuklamasi (0.4msm)" hisob-fakturalarni "SELECT." FROM "schyot-fakturalari" Qaerda "fakturalar" ". . "user_id" = $ 1 LIMIT $ 2 [["user_id", 2], ["LIMIT", 11]] => # ] >

Yuqoridagi misol, user.invoices-ga qo'ng'iroq qilganda, foydalanuvchi hisob-fakturalari ro'yxatini olishimiz mumkinligini ko'rsatadi. Buni amalga oshirayotganda, ActiveRecord avtomatik ravishda ma'lumotlar bazasini so'rab, foydalanuvchi bilan bog'langan hisob-fakturalarni yukladi. Ushbu yondashuv ishlarni osonlashtiradi, kam kodni yozish yoki qo'shimcha qadamlar haqida tashvishlanishga majbur qiladi, lekin agar siz bir nechta foydalanuvchilarga murojaat qilsangiz va har bir foydalanuvchi uchun schyot-fakturalarni olsangiz muammo bo'lishi mumkin. Ushbu muammo "N + 1 muammosi" sifatida tanilgan.

ActiveRecord-da, "N + 1 muammosi" ni tuzatish taklif qilingan usuldan foydalanish hisoblanadi:

irb (asosiy): 022: 0> foydalanuvchi = User.includes (: fakturalar) .find (2) Foydalanuvchi yuki (0.3msm) "foydalanuvchilar" ni tanlang. * FROM "foydalanuvchilar" Qaerda "foydalanuvchilar" bor "id" = $ 1 LIMIT $ 2 [["id", 2], ["LIMIT", 1]] Hisob-faktura yuki (0.6ms) "hisob-fakturalarni" SELECT. * FROM "hisob-fakturalar" Qaerda "fakturalar". "User_id" = $ 1 [["user_id", 2]] => #  user.invoices => # ]>

Bunday holda, ActiveRecord foydalanuvchini olishda schyot-fakturalarni birlashtiradi (ko'rsatilgan SQL so'rovlarida ko'rsatilganidek).

Ekto

Siz allaqachon sezganingizdek, Ecto chindan ham sehrni yoki imkonsizlikni yoqtirmaydi. Bu ishlab chiquvchilardan o'zlarining maqsadlari to'g'risida aniq bo'lishlarini talab qiladi.

Ecto bilan user.invoices-dan foydalanishning bir xil usulini sinab ko'raylik:

iex (7)> ​​foydalanuvchi = Repo.get (Foydalanuvchi, 2)
[debug] QUERY OK manba = "foydalanuvchilar" db = 18.3ms dekod = 0.6ms
"ID", u0. "To'liq ism", u0. "Elektron pochta", u0. "Kiritilgan_at", u0. "Yangilangan" "foydalanuvchilar" dan "qaerda bo'lsa, u0" "id" = $ 1) [2] ni tanlang.
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
  elektron pochta: "barbara@gordon.test",
  to'liq nomi: "Barbara Gordon",
  id: 2,
  kiritilgan_at: ~ N [2018-01-02 10: 02: 00.000000],
  hisob-fakturalar: # Ecto.Association.NotLoaded ,
  yangilangan_at: ~ N [2018-01-02 10: 02: 00.000000]
}
iex (8)> user.invoices
# Ecto.Association.NotLoaded 

Natijada Ecto.Association.NotLoaded. Unchalik foydali emas.

Hisob-fakturalarga kirish uchun, dasturchi Ecto-ni oldindan yuklash funktsiyasidan foydalanib xabardor qilishi kerak:

iex (12)> foydalanuvchi = oldindan yuklash (Foydalanuvchi,: fakturalar) |> Repo.get (2)
[debug] QUERY OK manba = "foydalanuvchilar" db = 11.8ms
"ID", u0. "To'liq ism", u0. "Elektron pochta", u0. "Kiritilgan_at", u0. "Yangilangan" "foydalanuvchilar" dan "qaerda bo'lsa, u0" "id" = $ 1) [2] ni tanlang.
[debug] QUERY OK manbai = "fakturalar" db = 4.2ms
"ID", i0. "To'lov_method", i0. "To'langan_at", i0. "Foydalanuvchi_id", i0. "Kiritilgan_at", i0. "Yangilangan", i0. "Foydalanuvchi_id" "FROM" schyot-fakturalari "qaerda ( i0. "user_id" = $ 1) BUYURTMA, i0. "user_id" [2]
% Financex.Accounts.User {
  __meta__: # Ecto.Schema.Metadata <: yuklangan, "foydalanuvchilar">,
  elektron pochta: "barbara@gordon.test",
  to'liq nomi: "Barbara Gordon",
  id: 2,
  kiritilgan_at: ~ N [2018-01-02 10: 02: 00.000000],
  fakturalar: [
    % Financex.Hisob-fakturasi {
      __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
      id: 2,
      kiritilgan_at: ~ N [2018-01-03 08: 00: 00.000000],
      pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
      to'lov_metod: "Paypal",
      yangilangan_at: ~ N [2018-01-03 08: 00: 00.000000],
      foydalanuvchi: # Ecto.Association.NotLoaded ,
      user_id: 2
    }
  ],
  yangilangan_at: ~ N [2018-01-02 10: 02: 00.000000]
}

iex (15)> user.invoices
[
  % Financex.Hisob-fakturasi {
    __meta__: # Ecto.Schema.Metadata <: yuklangan, "fakturalar">,
    id: 2,
    kiritilgan_at: ~ N [2018-01-03 08: 00: 00.000000],
    pullik_at: #DateTime <2018-02-01 08: 00: 00.000000Z>,
    to'lov_metod: "Paypal",
    yangilangan_at: ~ N [2018-01-03 08: 00: 00.000000],
    foydalanuvchi: # Ecto.Association.NotLoaded ,
    user_id: 2
  }
]

ActiveRecord-ga o'xshab, o'z ichiga olgan schyot-fakturalarni olish bilan oldindan yuklash kiradi, bu esa ularni user.invoices-ga qo'ng'iroq qilish paytida taqdim etadi.

Taqqoslash

Yana bir bor, ActiveRecord va Ecto o'rtasidagi kurash ma'lum bir nuqta bilan tugaydi: ekspluatatsiya. Ikkala vosita ham ishlab chiquvchilarga assotsiatsiyalarga osongina kirishga imkon beradi, ammo ActiveRecord uni oddiy holga keltirsa ham, natijada kutilmagan xatti-harakatlar bo'lishi mumkin. Ecto WYSIWYG turiga amal qiladi, u faqat ishlab chiquvchi tomonidan aniqlangan so'rovda ko'rinadigan narsani bajaradi.

Reylar dasturning barcha turli qatlamlariga keshlash strategiyalaridan foydalanish va ularni targ'ib qilish bilan mashhur. Birgina misol, "ruscha qo'g'irchoq" ni keshlash usulidan foydalanish haqida, u butunlay "N + 1 muammosi" ga o'z sehrini amalga oshirish uchun keshlash mexanizmiga tayanadi.

Tasdiqlash

ActiveRecord-da mavjud bo'lgan ko'pgina tekshiruvlar Ecto-da mavjud. Bu erda umumiy tasdiqlarning ro'yxati va ActiveRecord va Ecto ularni qanday aniqlashi:

Aylantirmoq

U erda sizda: asosiy olma va apelsin taqqoslash.

ActiveRecord ma'lumotlar bazasi so'rovlarini bajarish qulayligiga e'tibor qaratadi. Uning xususiyatlarining aksariyati model sinflarining o'ziga qaratiladi, bu ishlab chiquvchilardan ma'lumotlar bazasini va bu kabi operatsiyalarning ta'sirini chuqur tushunishni talab qilmaydi. ActiveRecord sukut bo'yicha ko'p ishlarni bajaradi. Garchi bu ishni boshlashni osonlashtirsa-da, sahnada nima sodir bo'layotganini tushunishni qiyinlashtiradi va faqat "ActiveRecord" ga rioya qilgan holda ishlaydi.

O'z navbatida, Ecto ko'proq verbal kodni keltirib chiqaradigan aniqlikni talab qiladi. Foyda sifatida hamma narsa diqqat markazida, sahna ortida hech narsa bo'lmaydi va siz o'zingizning yo'lingizni ko'rsatishingiz mumkin.

Ikkalasi ham sizning nuqtai nazaringiz va afzal ko'rgan narsalaringizga qarab o'zgaradi. Shunday qilib, olma va apelsinlarni taqqoslab, biz bu BAT-stulning oxiriga yetamiz. Sizga BatGirlning kod nomi (1989–2001) deb aytishni deyarli unutgan edingiz. Oracle. Ammo bunga yo'l qo'ymang.

Ushbu post mehmon muallifi Elvio Vikosa tomonidan yozilgan. Elvio - Rels ishlab chiqaruvchilari uchun Feniks kitobining muallifidir.

Dastlab blog.appsignal.com saytida 2018 yil 9 oktyabrda e'lon qilingan.