Saat membuat aplikasi di Laravel 4 setelah membaca buku T. Otwell tentang pola desain yang baik di Laravel, saya mendapati diri saya membuat repositori untuk setiap tabel pada aplikasi.
Saya berakhir dengan struktur tabel berikut:
- Siswa: id, name
- Kursus: id, nama, teacher_id
- Guru: id, nama
- Tugas: id, name, course_id
- Skor (bertindak sebagai poros antara siswa dan tugas): student_id, assignment_id, skor
Saya memiliki kelas repositori dengan metode temukan, buat, perbarui, dan hapus untuk semua tabel ini. Setiap repositori memiliki model Eloquent yang berinteraksi dengan database. Hubungan ditentukan dalam model sesuai dengan dokumentasi Laravel: http://laravel.com/docs/eloquent#relationships .
Saat membuat kursus baru, yang saya lakukan hanyalah memanggil metode create di Course Repository. Kursus itu memiliki tugas, jadi saat membuatnya, saya juga ingin membuat entri di tabel skor untuk setiap siswa dalam kursus. Saya melakukan ini melalui Assignment Repository. Ini menyiratkan repositori tugas berkomunikasi dengan dua model Eloquent, dengan model Tugas dan Siswa.
Pertanyaan saya adalah: karena aplikasi ini mungkin akan tumbuh dalam ukuran dan lebih banyak hubungan akan diperkenalkan, apakah itu praktik yang baik untuk berkomunikasi dengan model Eloquent yang berbeda di repositori atau haruskah ini dilakukan menggunakan repositori lain sebagai gantinya (maksud saya memanggil repositori lain dari repositori Tugas ) atau haruskah itu dilakukan bersama-sama dalam model Eloquent?
Juga, apakah praktik yang baik untuk menggunakan tabel skor sebagai poros antara tugas dan siswa atau haruskah itu dilakukan di tempat lain?
$a = $this->account->getById(1)
saya, saya tidak bisa begitu saja metode rantai seperti$a->getActiveUsers()
. Oke, saya bisa menggunakan$a->users->...
, tapi kemudian saya mengembalikan koleksi Eloquent dan tidak ada objek stdClass dan terikat ke Eloquent lagi. Apa solusinya? Mendeklarasikan metode lain di repositori pengguna seperti$user->getActiveUsersByAccount($a->id);
? Akan sangat senang mendengar bagaimana Anda mengatasi ini ...Saya menyelesaikan proyek besar menggunakan Laravel 4 dan harus menjawab semua pertanyaan yang Anda ajukan sekarang. Setelah membaca semua buku Laravel yang tersedia di Leanpub, dan banyak sekali Googling, saya menemukan struktur berikut.
Jadi katakanlah saya sedang membangun database film. Saya akan memiliki setidaknya kelas-kelas Model Eloquent berikut:
Sebuah kelas repositori akan merangkum setiap kelas Model Eloquent dan bertanggung jawab untuk operasi CRUD pada database. Kelas repositori mungkin terlihat seperti ini:
Setiap kelas repositori akan memperluas kelas BaseRepository yang mengimplementasikan antarmuka berikut:
Kelas Service digunakan untuk merekatkan beberapa repositori bersama-sama dan berisi "logika bisnis" aplikasi yang sebenarnya. Pengontrol hanya berkomunikasi dengan kelas Layanan untuk tindakan Buat, Perbarui, dan Hapus.
Jadi, ketika saya ingin membuat rekaman Film baru di database, kelas MovieController saya mungkin memiliki metode berikut:
Terserah Anda untuk menentukan bagaimana Anda POST data ke pengontrol Anda, tetapi katakanlah data yang dikembalikan oleh Input :: all () dalam metode postCreate () terlihat seperti ini:
Karena MovieRepository seharusnya tidak mengetahui cara membuat rekaman Aktor, Sutradara, atau Studio di database, kami akan menggunakan kelas MovieService kami, yang mungkin terlihat seperti ini:
Jadi yang tersisa adalah pemisahan perhatian yang baik dan masuk akal. Repositori hanya mengetahui model Eloquent yang mereka sisipkan dan ambil dari database. Pengontrol tidak peduli dengan repositori, mereka hanya menyerahkan data yang mereka kumpulkan dari pengguna dan meneruskannya ke layanan yang sesuai. Layanan tidak peduli bagaimana data yang diterimanya disimpan ke database, itu hanya menyerahkan data relevan yang diberikan oleh pengontrol ke repositori yang sesuai.
sumber
$studio->movies()->associate($movie);
).Saya suka memikirkannya dalam kaitannya dengan apa yang dilakukan kode saya dan apa yang menjadi tanggung jawabnya, daripada "benar atau salah". Beginilah cara saya memisahkan tanggung jawab saya:
Dengan pemikiran ini, masuk akal setiap kali menggunakan repositori (apakah Anda membuat interfaces.etc. Adalah topik yang sama sekali lain). Saya suka pendekatan ini, karena itu berarti saya tahu persis ke mana harus pergi ketika saya perlu melakukan pekerjaan tertentu.
Saya juga cenderung membangun repositori dasar, biasanya kelas abstrak yang mendefinisikan default utama - pada dasarnya operasi CRUD, dan kemudian setiap anak dapat memperluas dan menambahkan metode seperlunya, atau membebani default. Menyuntikkan model Anda juga membantu pola ini menjadi cukup kuat.
sumber
Pikirkan Repositori sebagai lemari arsip yang konsisten untuk data Anda (bukan hanya ORM Anda). Idenya adalah Anda ingin mengambil data dengan mudah menggunakan API yang konsisten.
Jika Anda menemukan diri Anda hanya melakukan Model :: all (), Model :: find (), Model :: create (), Anda mungkin tidak akan mendapat banyak manfaat dari mengabstraksi repositori. Di sisi lain, jika Anda ingin melakukan lebih banyak logika bisnis ke kueri atau tindakan Anda, Anda mungkin ingin membuat repositori untuk mempermudah penggunaan API untuk menangani data.
Saya pikir Anda bertanya apakah repositori akan menjadi cara terbaik untuk menangani beberapa sintaks lebih verbose yang diperlukan untuk menghubungkan model terkait. Bergantung pada situasinya, ada beberapa hal yang dapat saya lakukan:
Menggantung model anak baru dari model induk (satu-satu atau satu-banyak), saya akan menambahkan metode ke repositori anak seperti
createWithParent($attributes, $parentModelInstance)
dan ini hanya akan menambahkan$parentModelInstance->id
ke dalamparent_id
bidang atribut dan memanggil buat.Melampirkan hubungan banyak-banyak, saya sebenarnya membuat fungsi pada model sehingga saya dapat menjalankan $ instance-> attachChild ($ childInstance). Perhatikan bahwa ini membutuhkan elemen yang ada di kedua sisi.
Membuat model terkait dalam sekali jalan, saya membuat sesuatu yang saya sebut Gateway (mungkin agak lepas dari definisi Fowler). Cara saya dapat memanggil $ gateway-> createParentAndChild ($ parentAttributes, $ childAttributes) alih-alih sekumpulan logika yang dapat berubah atau yang akan memperumit logika yang saya miliki di controller atau perintah.
sumber