Monday, January 30, 2012

Re: Help Understanding Fat Models

Great explaniation Jeremy! +1

I recently got my head around the principle too. I'd recomend it
included in the cookbook alongside MVC introduction to reinforce the
DRY concept. Essential learning for more complex systems.

On Jan 30, 9:52 pm, jeremyharris <funeralm...@gmail.com> wrote:
> The best advice is to keep things DRY (Don't Repeat Yourself). Generally,
> this results in thin controllers (small controller functions) and fat
> models (more methods on the models). Any functionality that you will find
> yourself reusing across different controllers that appropriately relate to
> a model should be on that model, instead.
>
> As an example (typical blog example).
>
> //posts_controller
> function edit($id) {
> // check if user is the creator of this post and is therefore allowed to
> edit
> $post = $this->Post->read(null, $id);
> if (empty($post) || $post['Post']['created_by'] != $this->Auth->user('id'))
> {
> //redirect
> return;
>
> }
> }
>
> function delete($id) {
> // check if user has rights to delete
> $post = $this->Post->read(null, $id);
> if (empty($post) || $post['Post']['created_by'] != $this->Auth->user('id'))
> {
> //redirect
> return;
>
> }
> }
>
> Your controller would be considered "fat" because you duplicated code and
> this is logic that belongs in the model. Instead, something like this looks
> better:
>
> // post model
> function userOwnsPost($userId, $postId) {
> return $this->hasAny(array(
> 'id' => $postId,
> 'created_by' => $userId
> ));
>
> }
>
> // posts controller
> function edit($id) {
> if (!$this->Post->userOwnsPost($this->Auth->user('id'), $id)) {
> //redirect
>
> }
> }
>
> function delete($id) {
> if (!$this->Post->userOwnsPost($this->Auth->user('id'), $id)) {
> //redirect
>
> }
> }
>
> Perhaps not the *best* example, but you get the idea. This code is also
> much easier to test. If you ever change the behavior of userOwnsPost, it
> will change across the app. It's also very specific, which makes writing
> tests really easy.
>
> If you find yourself writing long, complex find conditions and using them
> over and over again, they probably belong in model. Remember, many small
> functions are easier to test and predict the outcome than large functions.
>
> Another example might be finding a list of posts that belong to a tag. You
> would place this in your Post or Tag model, and might call it in
> /posts/index, /pages/home, /posts/view,
> /users/posts_in_tags_i_have_created, etc.
>
> For small apps, it may not be necessary to move these functions around!
> But, I'd say the more you have in models the better, even if only for
> testing's sake. It's easier to find out what went wrong when your methods
> are smaller and very specific. Controller methods are usually less specific
> than model methods.
>
> Hope that clears it up a bit.

--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.


To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php

No comments: