I am making a simple app where one can post any thing and anyone can comment on that post.
Do I need to create an entity group making every post as parent and comments as children?If I am wrong how to model the data having post and comment as entities? Documentation says there a limit of 1 write/sec If my app has high traffic like many people are commenting on the same post at the same time there will be a problem of transaction failure. How to solve this ?
Before you start coding on a new platform, first do a bit of research and try to fully understand all the features and nuances first.
To answer your question, YES, you can create an Entity Group with the original post as parent and then each comment as a child, but WHY?
What are you trying to achieve? Having a Post with comments attached to it, right? Why not just save all of them in ONE entity?
Entities have attributes (fields); so you can have POST, COMMENTS as field types of the Entity Thread. The COMMENTS attribute/field can be an array of strings or text or objects as you see fit.
So when you are displaying the data, fetch the Thread entity, and display its POST field (the original post), then underneath it, display the COMMENTS field (extract strings from the string array then display them in order).
Related
I have a forum with a lot of topics (written in Angular+Laravel+Xampp), and I wondered how I should display the last comment when the user don't open specific topic, only seeing the headers/titles.
My structure is: There are sections (categories), and a section can have many topics, and a topic can have many posts, and a post can have many comments.
When a user views all the sections (the biggest categories), I wanna display for each of them the last messages in those topics'.
I could just search for every post and see which one of them has the latest comment, but then I should search through all the comments which seems a little redundant.
Maybe I should make a column e.g. "last_comment" for the sections table, and update it every time a post get a comment?
What is the best approach?
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I am creating a REST API and I have, for example, Authors and Posts.
So I can get the posts published by an author with:
/authors/123/posts
Or
/posts?authorId=123
I think building a flexible API might be a better option. To get posts by author I would do:
/posts?authorId=123&published=true&sort=created&expand=tags,category
So in this case I am getting all posts from authorId=123 that are published sort them by created date and also get the tags and category of each post.
Basically, I create a query language that kind of maps to each database table.
Then for common queries I create specific endpoints:
/posts/recent
Would return recent posts independently of the author ...
I think /authors/123/posts might become complex when using many levels.
What do you think?
UPDATE
After a few answers my idea is the following:
When Posts and Authors are two resources I would have (example for posts):
GET /posts?authorId=123&published=true
POST /posts
PUT /posts
DELETE /posts/123
If there is hierarchical dependency between Posts and Authors and I often need posts by author I would also add the following:
GET /authors/123/posts&published=true
If posts would not exist outside of resource Author then the 2 previous options would be replaced by:
GET /authors/123/posts?published=true
POST /authors/123/posts
PUT /authors/123/posts
DELETE /authors/123/posts/123
What do you think?
There is a myth that each resource must have only one path. Both of your examples are correct.
With your first example:
/authors/123/posts.
It makes sense when there is a hierarchical relationship between the two, if your current context is an author, it's no problem accessing posts of that author.
With your second example:
/posts?authorId=123&published=true&sort=created&expand=tags,category.
It makes sense to query the entire repository of posts distributed in many facets. For example, on your application, you may have a search page to search posts, it's the perfect use case for that.
Speaking in terms of model-view. Our resource is like model, our urls are like views. Nothing stops us from using many views for the same model. You just need to ensure you use the same backing code to access your stored data. There are different ways (views) to look at your data.
Summary: You can use both urls in your project. For example, use the /authors/123/posts on your author page to list posts of an author and use the /posts?authorId=123&published=true&sort=created&expand=tags,category on your post search page.
You could also have a look at this post for a similar opinion: What are best practices for REST nested resources
The rule of thumb we use on our projects: use a url path, e.g. /authors/123/posts if there is a clear hierarchical relationship between the two, and the resource you're visiting cannot live outside the context of the other one. For example, when retrieving order lines, it is straightforward to use /orders/123/lines, because an orderline has no meaning outside the context of the order itself.
In your case, posts can clearly 'live' outside the context of their author. If you can search posts by author, date, subject,... it makes sense to pass these values as a query string. So in my opinion, /posts?authorId=123 is the way to go here.
I have a question about the scalability of getting the many from a one-to-many relationship in parse.com. Below is a diagram of what I am trying to do.
I have a Like object that has a userWhoLiked and a messageLiked attributes as pointers. My question is in regards to checking if a User has liked a message already when loading a feed of Message objects. I was thinking that I could write some cloud code that would return both the Message itself as well as information about if the User has already liked that object. However, I feel like this would be very inefficient. I would in essence have a query for all the Message objects (which will be n objects long), and then another query for finding if the User has already liked that Message object by going through all the Like objects n times and checking the userWhoLiked and messageLiked based on the user logged in and Message I am checking. I am going to use the pointer to build the one-to-many relationship because the number of Like objects will be arbitrarily large. Is the method that I have described (using cloud code and then checking the Like objects ) for getting if a user has liked an object is okay and scalable? Is there a better way, or any suggestions? I appreciate your time. Thanks.
Why not just do one query on Like objects where the userWhoLiked key is equal to the current user? This will return all of the objects which the current user has liked and you can also infer that all objects not included have not been liked.
In case you haven't checked it out yet, I'd highly recommend the Parse Anypic tutorial which has a very similar structure
Basically, I've implemented the HABTM successfully in CakePHP, but the trouble is, I don't understand why it works.
The thing I hate about the CakePHP cookbook is that is tells you what to do but make very little effort to explain the underlying segments of their code.
Essentially, my data model is like this.
Task HABTM Question
I don't understand this code fragment.
$this->set('questions', $this->Task->Question->find('list'))
In particular, what is $this->Task->Question supposed to accomplish?
Also how is the above code link to this code fragment in the view?
echo $this->Form->input('Question');
One thing that is very peculiar is that with the above code fragment, I get a multiple select option.
However, if I change the code to this,
echo $this->Form->input('question');
I get a single select drop down list.
I scoured the entire documentation and still cannot find a satisfactory explanation to my doubts.
Would really appreciate if anyone can clarify this issue for me.
1. Model chaining
When a model has an association to another model (like in your example an HABTM one) then you can call methods of the associated model by chaining it to the current model. This is explained early in Associations and an example of exactly how it works is given at the end of the first section.
When you are someplace in your TasksController normally you would expect that only your Task model would be available. Instead any association described in the Task model is chained to that model in the form of $this->Model1->Model2.
So $this->set('questions', $this->Task->Question->find('list')) means:
From current model Task that you know about, access the associated model Question and then call its find('list') method. Then $this->set the results to the view as variable questions.
2. FormHelper Conventions
When you use a CamelCased single name for field input, like in $this->Form->input('Question'); you are saying to FormHelper that the data contained in the questions variable come from a model named Question with a HABTM association, therefore they should be handled as a multiple select (as HABTM points to such an association).
With a field name of model_id, like in this example question_id, you're asking for a single select (select a single id of the connected model).
With anything else, FormHelper looks at the field definition and takes the decision itself, but of course your can override any default behavior you want using options.
This is explained in detail and I'm surprised you missed both. CakePHP has one of the best documentations available, almost everything you need is there.
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