MVC: the correct template for defining objects from another model

I use CakePHP2.3 and my application has many associations between models. It is very common that the action of the controller will include manipulating data from another model. So I started writing a method in the model class to keep the controllers skinny ... But in these situations, I'm never sure which model the method should go to?

Here is an example. Let's say I have two models: a book and an author. Posted by hasMany Book. In the / books / add view, I may need to show a drop-down list of popular authors so that the user can select as associated with this book. Therefore, I need to write a method in one of two models. Should I...

but. Write a method in the author model class and call this method from within the BooksController :: add () action ...

$this->Author->get_popular_authors() 

C. Write a method in the book model class that instantiates another model and uses its search functions ... Ex:

 //Inside Book::get_popular_authors() $Author = new Author(); $populars = $Author->find('all', $options); return $populars; 

I think my question is the same as asking the question: "What is the best practice for writing model methods that mainly relate to associations between another model?" What is the best way to decide which model this method should apply to? Thanks in advance.

PS: I'm not interested in whether you think CakePHP sucks or is not a “true” MVC. This question is about the MVC design pattern, not the structure (s).

+7
design-patterns activerecord cakephp
source share
4 answers

IMHO function should be in the model that most closely matches the data you are trying to get. Models are a "data layer".

So, if you choose "popular authors", the function should be in the Author model, etc.

Sometimes a function is not suitable for any model "purely", so you just select it and continue. There are much more productive design decisions to consider. :)


BTW, in Cake, related models can be accessed without getting a “different” model object. Therefore, if Book is associated with Author :

 //BooksController $this->Book->Author->get_popular_authors(); //Book Model $this->Author->get_popular_authors(); 

ref: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#relationship-types

+6
source share

Follow the coding standards: get_popular_authors (), this should be with the camel getPopularAuthors ().

My guess is that you want to display a list of popular authors. I would do this with an element and cache this element and extract data from this element with requestAction () to retrieve data from the Authors controller (the action calls the model method).

Thus, the code is in the “right” place, your item is cached (performance bonus) and reused anywhere.

It brings me back to

"what is best for writing model methods that primarily deal with associations between another model?"

In theory, you can fill your code with some model and call it through colleagues. I would say that common sense applies here: your method should be implemented in a model / controller that matches the majority. Is the user connected? User Model / Controller. Is this a user owned book? Book model / controller.

I would always try to keep in touch and put the code in a specific domain. See also separation of problems .

+2
source share

I think that the key point to answer your question is determined by your specifications: "... popular authors that the user can choose as related to this book."

This, in addition to the fact that you bring all the authors, makes me ask: What are the criteria that you will use to determine which authors are popular?

I doubt it, but if it depends on adding the current book or some previous fields entered by the user, it makes sense to make a decision B and write the logic inside the book model.

Most likely, solution A is correct, because your case needs code to find popular authors only in the action of adding a book controller. This "feature" is only an add action, so it must be encoded inside the "Author" model to retrieve the list and called by the "add" action when preparing the "empty" form to transfer the list to the view.

In addition, it makes sense to write some kind of similar code inside the book model, if you want, for example, display all other books from the same author.

In this case, you apparently need popular authors (who have more books?), So this is clearly an “extra feature” of the author’s model (which you can even code as a custom search method).

In any case, according to others, there is no need to reload the Author model, since it is automatically loaded through its link to Books.

+1
source share

Watch for premature optimization. Just create your project until it works. You can always optimize your mvc code or templates after looking at the code. And most importantly, when your project is carried out most of the time, you will see a clearer or better way to do it faster / smarter and better than you did before.

You cannot and will never create the perfect mvc or project in one go. You need to find a way to work with you as you like, and over time you will learn how to improve your coding.

See more about Premature Optimization.

0
source share

All Articles