Skip to content

Instantly share code, notes, and snippets.

@maxrice
Created December 7, 2018 04:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save maxrice/d744b4a5bff9ce135de9d9dd01a31664 to your computer and use it in GitHub Desktop.
Save maxrice/d744b4a5bff9ce135de9d9dd01a31664 to your computer and use it in GitHub Desktop.
Given the following partially shown implementation of a Rails 5 app to manage simple todo lists for users, what improvements or changes would you make? Feel free to change or remove existing files/classes, or add new ones in your answer. Assume that any files/classes not shown, e.g.TodoItem, routes.rb, etc, exist with reasonable implementations.
class TodoListsController < ApplicationController
before_action :set_current_user
def index
sort_by = params[:sort] || 'created_at'
sort_order = (params[:asc] == 'false') ? 'ASC' : 'DESC'
@lists = TodoList.where(user_id: User.current_user.id).order("#{sort_by} #{sort_order}")
end
def show
@list = TodoList.find(params[:id])
end
# Mark an item as done and return user back from whence they came!
def complete_item
TodoItem.find(params[:id]).complete!
redirect_to :back
end
def new
@list = TodoList.new
end
def create
@list = TodoList.new(params[:todo_list])
if @list.save!
redirect_to todo_lists_url
else
flash[:notice] = "Error saving list"
redirect_to new_todo_list_url
end
end
def set_current_user
User.set_current_user(session[:user_id])
end
end
class TodoItem < ApplicationRecord
belongs_to :todo_list
validates :title, presence: true
# Completes to do item, saving to database.
def complete!
update!(done: true)
end
end
class TodoList < ApplicationRecord
has_many :todo_items
belongs_to :user
before_save :set_usr
def formatted_title
title + (todo_items.empty? ' (Complete)' : '')
end
# Assign this list to the currently signed in user when it's created
def set_usr
self.user_id = User.current_user.id
save
end
end
class User < ApplicationRecord
has_many :todo_lists
def self.set_current_user(id)
return if @_current_user.present?
@_current_user = User.find(id)
end
# Avoid a DB query each time we need the currently logged in user
def self.current_user
@_current_user
end
end
<%-# Display the current user's lists along with any uncompleted items -%>
<% @lists.each do |list| %>
<h2><%= list.formatted_title %></h2>
<ul>
<% list.todo_items.where(done: false).each do |item| %>
<li><% item.title %> - <%= link_to "Done!", complete_item_todo_lists(item), method: :put %></li>
<% end %>
</ul>
<% end %>
<h2><%= @list.formatted_title %></h2>
<ul>
<% @list.todo_items.where(done: false).each do |item| %>
<li><% item.title %> - <%= link_to "Done!", complete_item_todo_lists(item), method: :put %></li>
<% end %>
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment