It depends like everything else.
I usually only place these in my model.
- Eloquent relationsjops
- Get Attributes
- Set Attributes
class Genre extends Model
{
public function setGenreAttribute($value)
{
$this->attributes['genre'] = ucwords(strtolower($value));
}
public function books()
{
return $this->hasMany(BookView::class);
}
}
And keep my eloquent and my validations inside my controllers.
class GenresController extends Controller
{
public function __construct()
{
$this->middleware('auth')->except(['index', 'show']);
}
protected function validateGenre(Request $request, $validationRules = [])
{
$rules = array_merge([
'genre' => 'required|unique:genres,genre'
], $validationRules);
$request->validate($rules);
}
public function index()
{
$genres = Genre::orderBy('genre')->get();
return view('genres.index', compact('genres'));
}
public function show($id)
{
$genre = Genre::findOrFail($id);
return view('genres.show', compact('genre'));
}
public function edit($id)
{
$genre = Genre::findOrFail($id);
return view('genres.edit')->with(['genre' => $genre]);
}
public function create()
{
return view('genres.create');
}
public function store(Request $request)
{
$this->validateGenre($request);
$genre = new Genre();
$genre->genre = $request->genre;
$genre->save();
return redirect('/genres')->with('status', $genre->genre . ' successfully added.');
}
public function update(Genre $genre, Request $request)
{
$this->validateGenre($request, ['id' => 'required|exists:genres']);
$genre->genre = $request->genre;
$genre->update();
return redirect('/genres')->with('status', $genre->genre . ' successfully updated.');
}
public function destroy(Genre $genre)
{
$genre->delete();
return redirect('/genres')->with('status', $genre->genre . ' successfully deleted.');
}
}
It's more a matter of taste in most situations at least for me. If I would have some really complex eloquent or raw SQL i would most likely push it to the model or in the case of the raw SQL push it into a database view. The good thing about the database view is that I can keep my eloquent clean and simple.
By doing this with five tables
DB::statement(
"CREATE OR REPLACE VIEW book_views AS
SELECT a.id author_id,
b.id book_id,
CONCAT(a.last_name, ', ', a.first_name) author_name,
b.title,
(SELECT ROUND(AVG(s.score), 1) FROM scores s WHERE s.book_id = b.id) rating,
b.series,
b.part,
b.released,
g.id genre_id,
g.genre,
f.id format_id,
f.format,
CASE series
WHEN 'Standalone' THEN b.released
ELSE (SELECT MIN(bi.released) FROM books bi WHERE bi.series = b.series)
END series_started
FROM authors a,
books b,
genres g,
formats f
WHERE a.id = b.author_id
AND b.genre_id = g.id
AND b.format_id = f.id"
);
I can still use a pretty simple eloquent query in my controller
public function index()
{
$books = BookView::orderBy('author_name')
->orderBy('series_started')
->orderBy('part')
->orderBy('released')
->orderBy('title')
->get();
return view('books.index')->with('books', $books);
}
However like I said before it's a matter of your preference or in worst case a matter of coding convention used by the company you are working for..