SailsJS Models: Dynamic recentHistory attribute of a model, how to implement - angularjs

I'm building a webapp and I have a model, lets call it "person" and "person" has an attribute "location." I want person to have another attribute, "recentHistory" that is an array with the last, say, 5 locations that the user has had. What is the best way to implement this? I've skimmed the docs and I'm not really sure. The frontend is in AngularJS if that matters (I don't think it should). Is the best implementation to use a beforeUpdate where if they are updating location, it adds it to that array (and pushes out the 3rd index of that array)?

You can either store the data as an array or use associations. If you want to manage the array then the beforeUpdate lifecycle callback will be perfect.

Related

Is it better to pass arrays in view or objects in MVC?

Referring to this question: https://softwareengineering.stackexchange.com/questions/218391/arrays-vs-objects-in-view-template
I was wondering what are the best practices to pass data from controller to view?
I'm currently working on php/Laravel and using service layer between controller and models. I'm not using repository layer yet, so just getting eloquent object from models and passing them to controller then view. The format is not persistent, at some location the data is being passed as eloquent object/collection and at some points it's being passed in an associative array format.
We know, the best practice is that our view should know least about the backend code/structure. If we pass an eloquent object to the view, then our view even knows the field names in models. This way, changing one model field name will break our code till the view.
If we pass array then we can definitely such kind of information? There is also some concept about DTO (Data transfer object), how it can help in hiding our data from view? I'm looking for a way through which my front-end and back-end least depend on each other.

What's the preferred way to go about using backbone with non-crud resources?

New to backbone/marionette, but I believe that I understand how to use backbone when dealing with CRUD/REST; however, consider something like results from a search query. How should one model this? Of course the results likely relate to some model(s), but they are not meant to be tied to said model(s).
Part of me thinks that I should use a collection using a model that doesn't actually sync with a data store through the server, but instead just exists as a means of a modeling a search result object.
Another solution could be to have a collection with no models and just override parse.
I assume that the former is preferred, but again I have no experience with the framework. If there's an alternative/better solution than those listed above, please advise.
I prefer having one object which is responsible for both request and response parsing. It can parse the response to appropriate models and nothing more. I mean - if some of those parsed models are required somewhere in your page, there is something that keeps reference to this wrapper object and takes models from response it requires via wrapper methods.
Another option is to have Radio (https://github.com/marionettejs/backbone.radio) in this wrapper - you will not have to keep wrapper object in different places but call for data via Radio.

MVC: Correct pattern to reference objects from a different model

I'm using CakePHP2.3 and my app has many associations between models. It's very common that a controller action will involve manipulating data from another model. So I start to write 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 in?
Here's an example. Say I have two models: Book and Author. Author hasMany Book. In the /books/add view I might want to show a drop-down list of popular authors for the user to select as associated with that book. So I need to write a method in one of the two models. Should I...
A. Write a method in the Author model class and call that method from inside the BooksController::add() action...
$this->Author->get_popular_authors()
B. Write a method in the Book model class that instantiates the other model and uses it's find 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 "what is the best practice for writing model methods that primarily deal with associations between another model?" How best to decide which model that method should belong to? Thanks in advance.
PS: I'm not interested in hearing whether you thinking CakePHP sucks or isn't "true" MVC. This question is about MVC design pattern, not framework(s).
IMHO the function should be in the model that most closely matches the data you're trying to retrieve. Models are the "data layer".
So if you're fetching "popular authors", the function should be in the Author model, and so on.
Sometimes a function won't fit any model "cleanly", so you just pick one and continue. There are much more productive design decisions to concern yourself with. :)
BTW, in Cake, related models can be accessed without fetching "other" the model object. So if Book is related to 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
Follow the coding standards: get_popular_authors() this should be camel cased getPopularAuthors().
My guess is further that you want to display a list of popular authors. I would implement this using an element and cache that element and fetching the data in that element using requestAction() to fetch the data from the Authors controller (the action calls the model method).
This way the code is in the "right" place, your element is cached (performance bonus) and reuseable within any place.
That brings me back to
"what is the best practice for writing model methods that primarily
deal with associations between another model?"
In theory you can stuff your code into any model and call it through the assocs. I would say common sense applies here: Your method should be implement in the model/controller it matches the most. Is it user related? User model/controller. Is it a book that belongs to an user? Book model/controller.
I would always try to keep the coupling low and put the code into a specific domain. See also separation of concerns.
I think the key point to answer your question is defined by your specifications: "... popular authors for the user to select as associated with that book.".
That, in addition to the fact that you fetch all the authors, makes me ask:
What is the criteria that you will use to determine which authors are popular?
I doubt it, but if that depends on the current book being added, or some previous fields the user entered, there's some sense in adopting solution B and write the logic inside the Book model.
More likely solution A is the correct one because your case needs the code to find popular authors only in the add action of the Book controller. It is a "feature" of the add action only and so it should be coded inside the Author model to retrieve the list and called by the add action when preparing the "empty" form to pass the list to the view.
Furthermore, it would make sense to write some similar code inside the Book model if you wanted, e.g., to display all the other books from the same author.
In this case you seem to want popular authors (those with more books ?), so this clearly is an "extra feature" of the Author model (That you could even code as a custom find method).
In any case, as stated by others as well, there's no need to re-load the Author model as it is automatically loaded via its association with Books.
Look out for Premature Optimization. Just build your project till it works. You can always optimize your code or mvc patterns after you do a review of your code. And most important after your project is done most of the time you will see a more clear or better way to do it faster/smarter and better than you did before.
You can't and never will build a perfect mvc or project in one time. You need to find yourself a way of working you like or prefer and in time you'll learn how to improve your coding.
See for more information about Premature Optimization

backbone can a collection contain model objects of different classes?

I am just beginning to use backbone.js for a new crash project. My app has a dynamic (data-driven) user menu. Each menu option is a set of graphs/small tables, of mixed types. For example, a Sales Overview menu option can have a page with 2 pie chart objects, 2 line charts, a bar chart, and so on. I don't know up front what the menu options are going to be, nor what each menu option will entail.
I am considering defining a bunch of generic model "classes" by extending Backbone.Model - PieModel, BarModel, DispersionModel, etc. And corresponding View classes that can render an object of a type - PieView, LineView, and so on. Then I can assemble a page by putting these together as defined by the dynamic configuration. Each model instance's data url can be easily generated on the fly, via the dynamic configuration..
My first concern was if Backbone supports a Collection of mixed Model types. This is instigated by presence of a "model" property for a Collection - does it assume homogeneity? But it also says a collection can hold an ordered set of models.... model attribute can be polymorphic... a method to get "models" held in the collection. Should I be reading this as "model objects"?
A "page" to me really is a collection of such objects. I would like to create a Collection on the fly and populate it with instances of different model types. And then render this through a View. Or, create a View with an array of various model objects and render the View, bypassing the Collection all together.
I will appreciate your inputs on the design I have outlined, and good reference on backbone, and clarity on how to deploy a Collection in mixed model cases? Perhaps there is a different, smarter way to handle such scenarios...
Thanks.
Collections only really use their model attribute when passing plain objects into its adder functions (e.g. add, push). If you take a look at the source, each adder function passes the input through _prepareModel, which checks if the input is an instance of a Backbone.Model. If it's not, it tries to instantiate a new model using the collection's model, otherwise it just returns the input untouched.
So as long as you're always adding real Model objects to your collections you should be fine using different types.
However, if you're planning to use aggregate functions that act on model attributes (e.g. pluck) you may run into errors when the function tries to get at an attribute that doesn't exist in one type of model (though most of the time I think it would just silently fail, which might be what you want).
I am not sure if I have 100% properly understood your scenario, however, I am not convinced you are thinking about this in the right way...
In my opinion, your models should contain the data, and views should represent them. As such, in a sales context you might have a SalesData model which could be displayed in PieView, BarView or TableView. Try to completely separate display logic from data - the type of chart falls under display logic in my opinion.
With the above approach, each page would then contain a set of different views, which you could potentially contain in a master view if you felt the need. Each view would have its own model (or collection depending on how you structure the data), which you can then update/manipulate using the normal Backbone methods.
As far as I know it is not possible for a collection to have different types of models contained within it, but even if it was, I would probably not recommend it as it would complicate the code a lot.
In terms of learning resources, here are a couple:
Learn Backbone JS compeltely -- javascriptissexy.com - this one is very thorough but will take some time to get through.
Backbone patterns - much quicker to get you in the right frame of mind.

Backbone: Many small requests for model changes vs one collection sync?

What is a general good practice for when some action - changes multiple models in Backbone.js:
Trigger multiple PUT requests for each mode.save()
Single request to sync the entire collection
In case if the quantity of the changed models greater than 1 - definitely it should be the second item.
Usually, good REST api practice seems to suggest that you should update, save, create, delete single instances of persistent elements. In fact, you will find that a Backbone.Collection object does not implement these methods.
Also, if you use a standard URI scheme for your data access point, you will notice that a collection does not have a unique id.
GET /models //to get all items,
GET /models/:id //to read an element,
PUT /models/:id //to update an element,
POST /models/:id //to create an element,
DELETE /models/:id //to delete an element.
If you need to update every model of a collection on the server at once, maybe you need to ask why and there might be some re-thinking of the model structure. Maybe there should be a separate model holding that common information.
As suggested by Bart, you could implement a PATCH method to update only changed attributes of a particular element, thus saving bandwidth.
I like the first option, but I'd recommend you implement a PATCH behavior (only send updated attributes) to keep the requests as small as possible. This method gives you a more native "auto-save" feel like Google Docs. Of course, this all depends on your app and what you are doing.

Resources