Skip to content

Instantly share code, notes, and snippets.

@reprah
Created October 11, 2013 16:55
Show Gist options
  • Save reprah/6938249 to your computer and use it in GitHub Desktop.
Save reprah/6938249 to your computer and use it in GitHub Desktop.
Rewriting the index action of SolutionsController in Rubeque
# the current index action in SolutionsController (for comparison purposes)
# app/controllers/solutions_controller.rb
def index
@problem = Problem.find(params[:problem_id]) rescue (redirect_to "/" and return)
if !current_user_admin? && (@problem.nil? || !@problem.solved?(current_user))
redirect_to @problem and return
end
@top_solutions = Solution.where(problem_id: @problem.id, user_id: { "$nin" => [current_user.id] }).
desc(:score).desc(:updated_at).page(params[:page] || 1)
@followed_solutions = current_user.users_followed.map {|u| u.solutions.where(problem_id: @problem.id).first}.compact
respond_to do |format|
format.html # index.html.erb
format.json { render json: @solutions }
end
end
# refactored index action using the service
def index
@problem = Problem.find(params[:problem_id]) rescue (redirect_to "/" and return)
if current_user && @problem
@solutions, @followed_solutions = SolutionService.new(user: current_user, problem: @problem, page: params[:page]).solutions
else
redirect to @problem and return
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: @solutions }
end
end
# service object
# app/services/solution_service.rb
class SolutionService
def initialize(args={})
@user = args.fetch(:user)
@problem = args.fetch(:problem)
@page = args.fetch(:page) || 1
end
def solutions
if @problem.solved?(@user) || @user.admin
# return the top solutions if they solved the problem
[top_solutions, followed_solutions]
else
# else, mark the problem as skipped and show the bottom ones
skip_problem
[bottom_solutions]
end
end
def skip_problem
@user.skipped_problems[@problem.id] = true
@user.save
end
def bottom_solutions
Solution.where(problem_id: @problem.id).asc(:score).limit(3).page(@page)
end
def top_solutions
Solution.where(problem_id: @problem.id, user_id: { "$nin" => [@user.id] }).
desc(:score).desc(:updated_at).page(@page)
end
def followed_solutions
@user.users_followed.map {|u| u.solutions.where(problem_id: @problem.id).first}.compact
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment