Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MediaRanker - Semret Nicodimos - Edges #24

Open
wants to merge 35 commits into
base: master
Choose a base branch
from

Conversation

snicodimos
Copy link

Media Ranker

Congratulations! You're submitting your assignment!

Comprehension Questions

Question Answer
Describe a custom model method you wrote. I didn't create a custom model. I was trying to create the voting sorting logic in the model but it didn't work so I had to keep it in the works controller.
Describe how you approached testing that model method. What edge cases did you come up with? none
What are session and flash? What is the difference between them? Both flash and session are both hash-like objects that rails provides. Flash is a short-lived object and session on the other hand is longer lived until you log out.
Describe a controller filter you wrote. find_logged_user is a controller filter utilized
What was one thing that you gained more clarity on through this assignment? Better understanding of the request cycle as well as nested and custom routes. Additionally, got clarity in design decisions on what tables to create and how to establish the relationships.
What is the Heroku URL of your deployed application? https://semnic-app.herokuapp.com
Do you have any recommendations on how we could improve this project for the next cohort? None. It was a good learning experience.

…_helper.rb, wrote one test for model for work
@droberts-sea
Copy link

Media Ranker

What We're Looking For

Feature Feedback
Core Requirements
Git hygiene yes
Comprehension questions yes
General
Rails fundamentals (RESTful routing, use of named paths) some extra routes
Views are well-organized (DRY, use of semantic HTML, use of partials) mostly - see inline
Errors are reported to the user mostly - no error when trying to vote for the same work twice, just a silent failure
Business logic lives in the models some - I like that you made voting rules be a validation, and the direction you're going with the scope is good, but you didn't quite follow through all the way.
Models are thoroughly tested, including relations, validations and any custom logic some - see inline
Wave 1 - Media
Splash page shows the three media categories yes
Basic CRUD operations on media are present and functional Update doesn't work!
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 yes
Optional - Styling
Bootstrap is used appropriately yes
Look and feel is similar to the original yes - good work!
Overall

Great job overall! Your implementation matches the demo site very closely, and I would say the learning goals for this assignment were definitely met. The one place where I see room for improvement is around working with custom model methods - you've made a good start here, but you should keep practicing this as we go forward.

As with any project of this size 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!

def update
work = Work.find_by(id: params[:id])

if @work.update(work_params)

Choose a reason for hiding this comment

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

Here you store the work in work, but call .update on @work. This is probably why updating fails.

# for top 10 movies
@movies = Work.where(category: "movie")
# sort by votes and take only 10 movies
@movies = (@movies.sort_by { |movie| -movie.votes_count}).take(10)

Choose a reason for hiding this comment

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

These long lines of database work would be great as model methods. That would help DRY out this code, and having it in a separate method would make the functionality simpler to test as well. Something like this:

class Work
  # ...
  def self.top_ten(category)
    works_for_category = Work.where(category: category)
    sorted_works = works_for_category.sort_by { |movie| -movie.votes_count}
    return sorted_works.first(10)
  end
end

validates :user_id, presence: true
validates :work_id, presence: true

validates_uniqueness_of :work_id, scope: :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 this tricky uniqueness scope figured out!

validates :title, :category, presence: true

validates_uniqueness_of :title, scope: :category
scope :featured, -> {order('votes_count DESC')}

Choose a reason for hiding this comment

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

I like the idea of using a scope along with the counter cache here to sort the votes.

First, featured might not be the best name for this, since it returns the entire list of works sorted by vote count. Something like by_vote_count might be a better name.

Second, you should be using this scope in your controller to get the top ten:

@movies = Work.where(category: 'album').featured.first(10)

This is the big benefit of defining functionality of a scope: you can invoke it not just on the Work class, but on any collection of Works you got from the database (like from .where).

<tr>
<%@works.each do |work| %>
<%if work.category == "album"%>
<td scope="row"><%=work.votes.count%></td>

Choose a reason for hiding this comment

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

You have the same code to show a list of works repeated 3 times. Could you use a view partial or a loop to DRY this up?

end

resources :users

Choose a reason for hiding this comment

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

I don't think you need all 7 restful routes for users - only index and show are needed for this project.

end
describe 'Validations' do
it 'valid when user and work ids are present' do
is_valid = @vote.valid?

Choose a reason for hiding this comment

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

Since this validation is complex, there are a couple other positive test cases I would like to see:

  • A user can have votes for two different works
  • A work can have votes from two different users


describe Work do
# describe 'relations' do
# it 'a vote can be set through the method work' do

Choose a reason for hiding this comment

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

It's difficult to write model tests if you didn't write model methods, but you should at least have tests for the featured scope here.

If you were to write a method to find the top ten works, I would look for the following cases:

  • What if there are no works of that category?
  • What if there are less than 10 works?
  • What if there's a tie for last place, e.g. works 9, 10 and 11 all have 0 votes?

Similarly, if you had a model method for finding the spotlight, I might ask:

  • What happens if there are no works?
  • What happens if there are works but no votes?
  • What happens if two works have the same number of votes?

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