Skip to content

Conversation

@norrise120
Copy link

@norrise120 norrise120 commented Apr 29, 2019

Media Ranker

Congratulations! You're submitting your assignment!

Comprehension Questions

Question Answer
Describe a custom model method you wrote. I wrote a custom method for the top ten works. It takes the category as a parameter and then finds all works for the category, sorts and then returns an array of ten or less items.
Describe how you approached testing that model method. What edge cases did you come up with?
What are session and flash? What is the difference between them? session is used by the browser to store information about the user. flash is used to send a message to the user.
What was one thing that you gained more clarity on through this assignment? MIGRATIONS! I had originally created a Vote model but then decided to create a join table instead. I knew that we were not supposed to delete migrations so I just tried until creating the vote model with my second migration. However something didnt work. I was finally able to fix that by going back a few commits. However, when I created my join table the second time, I thought it would be a good idea to change the name of the table to vote so it was clear what the table represented. This was a bad idea!!! It took me forever to realize that the reason I kept getting an error that there was no user, work relation is because I had renamed the table from the standard users_works.
What is the Heroku URL of your deployed application? https://eln-mediaranker.herokuapp.com/
Do you have any recommendations on how we could improve this project for the next cohort? I that the join table here was very different from the example in class and that we could benefit from going through them more.

While going through the building my index pages, I discovered that I was unable access any data that showed when a particular work was upvoted. As a result, I had to rework my models, removing my join table between works and users and creating a new vote model that had a many to one relationship with both user and work. This allowed me to access each particular votes created_at variable. It also I think made it more clear what I was doing in my html having work.votes rather than work.users to represent that votes.

Because I switched my design, a lot of my tests had to be rewritten. This is something that I am working on updating.

@droberts-sea
Copy link

Media Ranker

What We're Looking For

Feature Feedback
Core Requirements
Git hygiene
Comprehension questions
General
Rails fundamentals (RESTful routing, use of named paths) yes
Views are well-organized (DRY, use of semantic HTML, use of partials) yes
Errors are reported to the user yes
Business logic lives in the models some - see inline
Models are thoroughly tested, including relations, validations and any custom logic no
Controllers are thoroughly tested, including the login/logout process and multi-step workflows like voting for a work mostly - see inline
Wave 1 - Media
Splash page shows the three media categories yes
Basic CRUD operations on media are present and functional yes
Wave 2 - Users and Votes
Users can log in and log out yes
The ID of the current user is stored in the session yes
A user cannot vote for the same media more than once yes
All media lists are ordered by vote count yes
Splash page contains a media spotlight yes
Wave 3 - Users and Votes
Media pages contain lists of voting users yes
Individual user pages and the user list are present user list is there, individual pages are not
Optional - Styling
Bootstrap is used appropriately nope
Look and feel is similar to the original though there's not any styling, you've done a good job of matching the workflows and functionality of the original
Overall Good job overall! Aside from styling your implementation matches the demo site very closely, and I would say the learning goals for this assignment were definitely met. There are a few places where things could be cleaned up, which I've tried to outline below, but in general I am quite happy with this submission. Keep up the hard work!

resources :works
post "/works/:id/upvote", to: "works#upvote", as: "upvote"

resources :users, only: [:index, :show]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work generating only the routes you needed here.

@@ -0,0 +1,86 @@
class WorksController < ApplicationController
before_action :find_work, only: [:show, :edit, :update, :destroy, :upvote]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good use of a controller filter to help keep this file DRY

vote = Vote.find_by(user_id: session[:user_id], work_id: @work.id)
if vote
flash[:status] = :error
flash[:message] = "Cannot vote more than once"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this check to the model, possibly as a validation?

<% ["movie", "book", "album"].each do |type| %>
<section class="top-ten-container">
<h2>Top <%= type.capitalize%>s</h2>
<ul>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work keeping this DRY

<% end %>
</nav>

<body>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All HTML that appears on the page should be contained inside the <body> tag.

<% ordered_works = selected_works.sort_by do |work| %>
<% work.votes.length %>
<% end %>
<% ordered_works.reverse! %>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an awful lot of work to be doing in a view. Could you extract this to a model method? It would probably look pretty similar to your top_ten method.

<% Work.top_ten(type).each do |work| %>
<li>
<%= link_to work.title, work_path(work) %> by <%= work.creator %>
<%= work.votes.length%> votes

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a huge fan of you calling the model directly from the view - would it be possible to "tee up" this work in the controller?

describe HomepagesController do
# it "must be a real test" do
# flunk "Need real tests"
# end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this was missed. In addition to the nominal case, the media spotlight presents and interesting edge case where there are no works in the database.

describe "login" do
it "logs in an user" do
new_user = User.create(username: "newuser")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a couple of behavior modes you're not covering:

  • Logging in a new user (should create that user)
  • Attempting to log in with an invalid username (e.g. empty string) (should fail)


it "flashes an error if user already voted" do
post login_path, params: @login_data
expect(session[:user_id]).must_equal @user.id

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work getting the three interesting cases for upvote, especially since the testing logic is so tricky.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants