Skip to content

Instantly share code, notes, and snippets.

@dzhlobo
Created September 15, 2018 14:41
Show Gist options
  • Save dzhlobo/430482d06629f6136e2d27254604e715 to your computer and use it in GitHub Desktop.
Save dzhlobo/430482d06629f6136e2d27254604e715 to your computer and use it in GitHub Desktop.
class PostsController < ApplicationController
def index
render cell: :index, model: posts
end
def show
post_view_registrar.commit_view
show_post_page
end
private
def posts
Posts::Filter.new(params)
.filtered_posts
.includes(:related_posts, :categories)
.include_voted_by_user(current_user)
end
def post_view_registrar
@_post_view_registrar ||=
PostViewRegistrar.new(post: post, user: current_user, user_ip: request.remote_ip)
end
def show_post_page
if post.show_internally?
render cell: :show, model: post, layout: "post_layout"
else
redirect_to post.link
end
end
def post
@_post ||= Post.include_voted_by_user(current_user).find(params[:id])
end
end
class Posts::Filter
def initialize(params)
@params = Params.new(params)
end
def filtered_posts
filters.reduce(all_posts) do |posts, filter|
filter.call(posts)
end
end
private
attr_reader :params
def all_posts
::Post.all
end
def filters
[page_filter, time_filter, sorting_filter, source_filter, search_filter, category_filter]
end
def page_filter
->(posts) { posts.paginate(page: params.page) }
end
def time_filter
if params.all_time?
->(posts) { posts }
else
->(posts) { posts.published_later_than(beginning_time_from_params) }
end
end
def beginning_time_from_params
case params.time.to_sym
when :hourly
1.hour.ago
when :daily
1.day.ago
when :weekly
7.days.ago
when :monthly
1.month.ago
when :annually
1.year.ago
end
end
def sorting_filter
case params.set.to_sym
when :new
->(posts) { posts.ordered_by_date }
when :most_read
->(posts) { posts.ordered_by_views_count.ordered_by_date }
when :highly_voted
->(posts) { posts.ordered_by_voting_result.ordered_by_date }
when :most_reviewed
->(posts) { posts.order_by_review_rating.ordered_by_date }
when :most_covered
->(posts) { posts.ordered_by_coverage.ordered_by_voting_result.ordered_by_date }
end
end
def source_filter
if params.sources.present?
->(posts) { posts.source_posts(params.sources) }
else
->(posts) { posts }
end
end
def search_filter
if params.q.present?
->(posts) { posts.for_search_query(params.q) }
else
->(posts) { posts }
end
end
def category_filter
if params.categories.present?
->(posts) { posts.for_categories(params.categories) }
else
->(posts) { posts }
end
end
end
class Posts::Filter::Params
extend ActiveModel::Naming
extend Enumerize
def initialize(raw_params)
@page = raw_params[:page]
@q = raw_params[:q]
@set = raw_params[:set] || :highly_voted
@time = raw_params[:time] || :daily
@sources = raw_params[:sources]
@categories = raw_params[:categories]
end
attr_reader :page, :q, :sources, :categories
enumerize :set, in: [:new, :most_read, :highly_voted, :most_reviewed, :most_covered], default: :highly_voted
enumerize :time, in: [:hourly, :daily, :weekly, :monthly, :annually, :all_time], default: :daily, predicates: true
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment