Laravel 4 kullanarak büyük bir projeyi bitiriyorum ve şu anda sorduğunuz tüm soruları yanıtlamam gerekiyordu. Leanpub'daki mevcut tüm Laravel kitaplarını ve tonlarca Googling'i okuduktan sonra aşağıdaki yapıyı buldum.
- Tarihlenebilir tablo başına bir Eloquent Model sınıfı
- Her Eloquent Modeli için bir Depo sınıfı
- Birden çok Depo sınıfı arasında iletişim kurabilen bir Hizmet sınıfı.
Diyelim ki bir film veritabanı oluşturuyorum. En azından aşağıdaki Eloquent Model sınıflarına sahip olacaktım:
- Film
- Stüdyo
- yönetmen
- Aktör
- gözden geçirmek
Bir depo sınıfı, her bir Eloquent Model sınıfını kapsayacak ve veritabanı üzerindeki CRUD işlemlerinden sorumlu olacaktır. Depo sınıfları şöyle görünebilir:
- MovieRepository
- StudioRepository
- DirectorRepository
- ActorRepository
- ReviewRepository
Her depo sınıfı, aşağıdaki arabirimi uygulayan bir BaseRepository sınıfını genişletir:
interface BaseRepositoryInterface
{
public function errors();
public function all(array $related = null);
public function get($id, array $related = null);
public function getWhere($column, $value, array $related = null);
public function getRecent($limit, array $related = null);
public function create(array $data);
public function update(array $data);
public function delete($id);
public function deleteWhere($column, $value);
}
Bir Service sınıfı, birden çok depoyu birbirine yapıştırmak için kullanılır ve uygulamanın gerçek "iş mantığını" içerir. Denetleyiciler yalnızca Oluşturma, Güncelleme ve Silme eylemleri için Hizmet sınıflarıyla iletişim kurar.
Bu nedenle, veritabanında yeni bir Movie kaydı oluşturmak istediğimde, MovieController sınıfım aşağıdaki yöntemlere sahip olabilir:
public function __construct(MovieRepositoryInterface $movieRepository, MovieServiceInterface $movieService)
{
$this->movieRepository = $movieRepository;
$this->movieService = $movieService;
}
public function postCreate()
{
if( ! $this->movieService->create(Input::all()))
{
return Redirect::back()->withErrors($this->movieService->errors())->withInput();
}
// New movie was saved successfully. Do whatever you need to do here.
}
Verileri denetleyicilerinize nasıl POST yapacağınızı belirlemek size kalmıştır, ancak diyelim ki postCreate () yönteminde Input :: all () tarafından döndürülen veriler şuna benzer:
$data = array(
'movie' => array(
'title' => 'Iron Eagle',
'year' => '1986',
'synopsis' => 'When Doug\'s father, an Air Force Pilot, is shot down by MiGs belonging to a radical Middle Eastern state, no one seems able to get him out. Doug finds Chappy, an Air Force Colonel who is intrigued by the idea of sending in two fighters piloted by himself and Doug to rescue Doug\'s father after bombing the MiG base.'
),
'actors' => array(
0 => 'Louis Gossett Jr.',
1 => 'Jason Gedrick',
2 => 'Larry B. Scott'
),
'director' => 'Sidney J. Furie',
'studio' => 'TriStar Pictures'
)
MovieRepository'nin veritabanında Actor, Director veya Studio kayıtlarını nasıl oluşturacağını bilmemesi gerektiğinden, aşağıdaki gibi görünen MovieService sınıfımızı kullanacağız:
public function __construct(MovieRepositoryInterface $movieRepository, ActorRepositoryInterface $actorRepository, DirectorRepositoryInterface $directorRepository, StudioRepositoryInterface $studioRepository)
{
$this->movieRepository = $movieRepository;
$this->actorRepository = $actorRepository;
$this->directorRepository = $directorRepository;
$this->studioRepository = $studioRepository;
}
public function create(array $input)
{
$movieData = $input['movie'];
$actorsData = $input['actors'];
$directorData = $input['director'];
$studioData = $input['studio'];
// In a more complete example you would probably want to implement database transactions and perform input validation using the Laravel Validator class here.
// Create the new movie record
$movie = $this->movieRepository->create($movieData);
// Create the new actor records and associate them with the movie record
foreach($actors as $actor)
{
$actorModel = $this->actorRepository->create($actor);
$movie->actors()->save($actorModel);
}
// Create the director record and associate it with the movie record
$director = $this->directorRepository->create($directorData);
$director->movies()->associate($movie);
// Create the studio record and associate it with the movie record
$studio = $this->studioRepository->create($studioData);
$studio->movies()->associate($movie);
// Assume everything worked. In the real world you'll need to implement checks.
return true;
}
Öyleyse bıraktığımız şey, endişelerin hoş ve mantıklı bir ayrımı. Depolar yalnızca ekledikleri ve veritabanından aldıkları Eloquent modelinin farkındadır. Denetleyiciler depoları önemsemezler, sadece kullanıcıdan topladıkları verileri verirler ve uygun hizmete iletirler. Hizmet, aldığı verilerin veri tabanına nasıl kaydedildiğini umursamaz , sadece denetleyici tarafından verilen ilgili verileri uygun depolara verir.