Almost at the end of Lesson 3, i decided to add a couple of additional features to my PostIt web application i am developing as a part of the second course at Tealeaf Academy
Here are the two features i have attempted to add:
In the default application (as instructed in the course), the only way to create a new category was through the Categories dropdown button in the navigation bar as show in the image below:
This is not very helpful when a user would want to add a new category during creation of a new post. So, i added a new category creation form inside the Posts-new view template. But that meant making sure the validation on the category name fired from here without destroying the new post contents. This also necessitated the use of non-model backed form helpers (although Category is a model, the text-field to pass new category name is not in a Category model-backed form).
This helper in the Posts controller class helps to determine whether to create a new category or not:
The following code in the Posts#create uses the above helper:
posts_controller.rb : create
12345678910111213141516171819
category_index=create_new_categoryifcategory_indexflash[:notice]="Category & Post created successfully!"category_check_passed=trueelsif@categorycategory_check_passed=@category.errors.empty?elsecategory_check_passed=trueendif@post.save&&category_check_passed@post.categories<<@categoryifcategory_indexflash[:notice]||="Post created successfully!"redirect_toposts_pathelse@new_category=params[:new_category]render:newend
It is used in a similar way in the Posts#update action.
Here's how it looks in the create-new-post form now:
If, new category creation fails:
Here's the post after the validation passes:
The changes in the form partial are highlighted in the git-diff below:
One user cannot vote more than once on a post or a comment through this validation in the Votes model: validates_uniqueness_of :creator, scope: [:voteable_type, :voteable_id]
What if a user voted by mistake or changed his/her mind on a particular post or comment? Adding this capability meant that I needed to do primarily two things:
If the logged in user has voted (up or down) on a particular item, show an icon to delete the vote instead of an icon to cast a vote (the thumbs-up or thumbs-down icon)
The vote deletion icon should call an action to delete this user's vote on that item
I added these by writing one helper method for each 'voteable' model, comment, and post. Shown below is the one for comment (the more complex of the two). The one for post is very similar.
Using this helper method in the view template is illustrated below:
_comments.html.erb
123456789
<% if logged_in?%> <%= link_based_on_current_users_vote_on_comment(comment, true) %><br><% end %> <%= "<strong>#{comment.vote_count}</strong> <small>(#{pluralize(comment.votes.size, "Vote")})</small>".html_safe %><% if logged_in?%> <br><%=link_based_on_current_users_vote_on_comment(comment,false)%> <% end %>