Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ gem "mini_racer", "~> 0.6.2"

gem "unicorn", "~> 6.1"

gem "redis-rails", "~> 5.0", ">= 5.0.2"

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem "byebug", platforms: [:mri, :mingw, :x64_mingw]
Expand Down
17 changes: 17 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,22 @@ GEM
rb-inotify (0.10.1)
ffi (~> 1.0)
redis (4.6.0)
redis-actionpack (5.3.0)
actionpack (>= 5, < 8)
redis-rack (>= 2.1.0, < 3)
redis-store (>= 1.1.0, < 2)
redis-activesupport (5.3.0)
activesupport (>= 3, < 8)
redis-store (>= 1.3, < 2)
redis-rack (2.1.4)
rack (>= 2.0.8, < 3)
redis-store (>= 1.2, < 2)
redis-rails (5.0.2)
redis-actionpack (>= 5.0, < 6)
redis-activesupport (>= 5.0, < 6)
redis-store (>= 1.2, < 2)
redis-store (1.9.1)
redis (>= 4, < 5)
regexp_parser (2.1.1)
representable (3.1.1)
declarative (< 0.1.0)
Expand Down Expand Up @@ -497,6 +513,7 @@ DEPENDENCIES
rack-mini-profiler (~> 2.0)
rails (~> 6.1.3)
rails-controller-testing (~> 1.0, >= 1.0.5)
redis-rails (~> 5.0, >= 5.0.2)
rspec-rails (~> 5.0, >= 5.0.2)
sass-rails (>= 6)
selenium-webdriver
Expand Down
6 changes: 6 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
module ApplicationHelper
def collection_cache_helper_for(model)
klass = model.to_s.capitalize.constantize
count = klass.count
max_updated_at = klass.maximum(:updated_at).try(:utc).try(:to_s, :number)
"#{model.to_s.pluralize}/collection-#{count}-#{max_updated_at}"
end
end
2 changes: 1 addition & 1 deletion app/models/answer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Answer < ApplicationRecord
include Votable
include Commentable

belongs_to :question
belongs_to :question, touch: true
belongs_to :author, class_name: "User"
has_many :links, dependent: :destroy, as: :linkable

Expand Down
2 changes: 1 addition & 1 deletion app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
belongs_to :commentable, polymorphic: true, touch: true

validates :body, presence: true
end
2 changes: 1 addition & 1 deletion app/models/link.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Link < ApplicationRecord
belongs_to :linkable, polymorphic: true
belongs_to :linkable, polymorphic: true, touch: true

validates :name, :url, presence: true
validates :url, format: URI::regexp(%w[http https])
Expand Down
2 changes: 1 addition & 1 deletion app/models/subscription.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Subscription < ApplicationRecord
belongs_to :user
belongs_to :question
belongs_to :question, touch: true

validates :user, uniqueness: { scope: :question_id }
end
2 changes: 1 addition & 1 deletion app/models/vote.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Vote < ApplicationRecord
belongs_to :user
belongs_to :votable, polymorphic: true
belongs_to :votable, polymorphic: true, touch: true

validates :status, presence: true
validates :user, uniqueness: { scope: %i[votable_type votable_id] }
Expand Down
67 changes: 34 additions & 33 deletions app/views/answers/_answer.html.slim
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
li id="answer-li-#{answer.id}"
p = answer.body
- if (can? :destroy, answer) && (can? :update, answer)
p = link_to 'Delete answer', answer_path(answer), method: :delete, data: { confirm: "Are you sure?" }, remote: true
p = link_to "Edit", "#", class: "edit-answer-link", data: { answer_id: answer.id }
= form_with model: answer, local: false, class: 'hidden', html: {id: "edit-answer-#{answer.id}"} do |f|
= f.label :body
= f.text_area :body
p
= f.label :files
= f.file_field :files, multiple: true
p Links:
p
= f.fields_for :links do |link|
= render 'link_fields', f: link
.links
= link_to_add_association 'Add link', f, :links
= f.submit 'Save'
- if can?(:mark_as_best, @question)
p = link_to 'Mark answer as best', mark_answer_as_best_question_path(@question, answer_id: answer.id), method: :patch
= render 'shared/attached_files', resource: answer
.answer-links
= render 'shared/attached_links', resource: answer
.answer-vote
= render 'shared/vote', resource: answer
div id="answer-#{answer.id}-comments"
- if answer.comments.first
h4 = "Comments:"
ul
= render answer.comments
- if user_signed_in?
p = link_to 'Add comment', "#", class: "add-comment", data: { answer_id: answer.id }
= render 'comments/form', commentable: answer
- cache answer do
li id="answer-li-#{answer.id}"
p = answer.body
- if (can? :destroy, answer) && (can? :update, answer)
p = link_to 'Delete answer', answer_path(answer), method: :delete, data: { confirm: "Are you sure?" }, remote: true
p = link_to "Edit", "#", class: "edit-answer-link", data: { answer_id: answer.id }
= form_with model: answer, local: false, class: 'hidden', html: {id: "edit-answer-#{answer.id}"} do |f|
= f.label :body
= f.text_area :body
p
= f.label :files
= f.file_field :files, multiple: true
p Links:
p
= f.fields_for :links do |link|
= render 'link_fields', f: link
.links
= link_to_add_association 'Add link', f, :links
= f.submit 'Save'
- if can?(:mark_as_best, @question)
p = link_to 'Mark answer as best', mark_answer_as_best_question_path(@question, answer_id: answer.id), method: :patch
= render 'shared/attached_files', resource: answer
.answer-links
= render 'shared/attached_links', resource: answer
.answer-vote
= render 'shared/vote', resource: answer
div id="answer-#{answer.id}-comments"
- if answer.comments.first
h4 = "Comments:"
ul
= render answer.comments
- if user_signed_in?
p = link_to 'Add comment', "#", class: "add-comment", data: { answer_id: answer.id }
= render 'comments/form', commentable: answer
7 changes: 4 additions & 3 deletions app/views/comments/_comment.html.slim
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
li id="comment-#{comment.id}"
p = comment.body
p = "Author: #{comment.user.email}"
- cache comment do
li id="comment-#{comment.id}"
p = comment.body
p = "Author: #{comment.user.email}"
19 changes: 10 additions & 9 deletions app/views/questions/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ p= link_to 'Ask question', new_question_path

h2 Questions list

table class="questions-index-table"
tr
th
p Question title
th
p Question Body
th
p View question
= render @questions
-cache collection_cache_helper_for :question do
table class="questions-index-table"
tr
th
p Question title
th
p Question Body
th
p View question
= render @questions

- if current_user
p = link_to 'View Awards', awards_path
147 changes: 74 additions & 73 deletions app/views/questions/show.html.slim
Original file line number Diff line number Diff line change
@@ -1,80 +1,81 @@
.question
.question-errors
h1 Question title
h3 id="question-title-#{@question.id}" = @question.title
- if can?(:update, @question)
p = link_to 'Edit title', "#", class: "edit-question-title-link", data: { question_id: @question.id }
= form_with model: @question, local: false, class: 'hidden', html: {id: "edit-question-title-#{@question.id}"} do |f|
= f.label :title
= f.text_area :title
= f.submit 'Save'
- cache @question do
.question
.question-errors
h1 Question title
h3 id="question-title-#{@question.id}" = @question.title
- if can?(:update, @question)
p = link_to 'Edit title', "#", class: "edit-question-title-link", data: { question_id: @question.id }
= form_with model: @question, local: false, class: 'hidden', html: {id: "edit-question-title-#{@question.id}"} do |f|
= f.label :title
= f.text_area :title
= f.submit 'Save'

h1 Question body
h3 id="question-body-#{@question.id}" = @question.body
- if can?(:update, @question)
p = link_to 'Edit body', "#", class: "edit-question-body-link", data: { question_id: @question.id }
= form_with model: @question, local: false, class: 'hidden', html: {id: "edit-question-body-#{@question.id}"} do |f|
= f.label :body
= f.text_area :body
p
= f.label :files
= f.file_field :files, multiple: true
p Links:
p
= f.fields_for :links do |link|
= render 'link_fields', f: link
.links
= link_to_add_association 'Add link', f, :links
= f.submit 'Save'
h1 Question body
h3 id="question-body-#{@question.id}" = @question.body
- if can?(:update, @question)
p = link_to 'Edit body', "#", class: "edit-question-body-link", data: { question_id: @question.id }
= form_with model: @question, local: false, class: 'hidden', html: {id: "edit-question-body-#{@question.id}"} do |f|
= f.label :body
= f.text_area :body
p
= f.label :files
= f.file_field :files, multiple: true
p Links:
p
= f.fields_for :links do |link|
= render 'link_fields', f: link
.links
= link_to_add_association 'Add link', f, :links
= f.submit 'Save'

.question-files-list
= render 'shared/attached_files', resource: @question
.question-files-list
= render 'shared/attached_files', resource: @question

.question-links
= render 'shared/attached_links', resource: @question
.question-award
= render 'shared/attached_award', resource: @question.award
.question-vote
= render 'shared/vote', resource: @question
div id="question-#{@question.id}-comments"
- if @question.comments.first
h4 = "Comments:"
ul
= render @question.comments
- if user_signed_in?
p = link_to 'Add comment', "#", class: "add-comment", data: { question_id: @question.id }
= render 'comments/form', commentable: @question
.question-subscribed
- if user_signed_in?
= render 'shared/subscription', resource: @question
.question-links
= render 'shared/attached_links', resource: @question
.question-award
= render 'shared/attached_award', resource: @question.award
.question-vote
= render 'shared/vote', resource: @question
div id="question-#{@question.id}-comments"
- if @question.comments.first
h4 = "Comments:"
ul
= render @question.comments
- if user_signed_in?
p = link_to 'Add comment', "#", class: "add-comment", data: { question_id: @question.id }
= render 'comments/form', commentable: @question
.question-subscribed
- if user_signed_in?
= render 'shared/subscription', resource: @question

h2 = "Answers list"
.answer-errors
.answers
ol
- if @best_answer.present?
.best-answer
= render @best_answer
= render @other_answers
h2 = "Answers list"
.answer-errors
.answers
ol
- if @best_answer.present?
.best-answer
= render @best_answer
= render @other_answers

- if current_user
h2 Create new answer
.answer-errors-create
= form_with model: [@question, @answer], local: false do |f|
= f.label :body
= f.text_area :body
p
= f.label :files
= f.file_field :files, multiple: true
p Links:
p
= f.fields_for :links do |link|
= render 'link_fields', f: link
.links
= link_to_add_association 'Add link', f, :links
= f.submit 'Create'
- if current_user
h2 Create new answer
.answer-errors-create
= form_with model: [@question, @answer], local: false do |f|
= f.label :body
= f.text_area :body
p
= f.label :files
= f.file_field :files, multiple: true
p Links:
p
= f.fields_for :links do |link|
= render 'link_fields', f: link
.links
= link_to_add_association 'Add link', f, :links
= f.submit 'Create'

p = link_to 'Back to questions list', questions_path
p = link_to 'Back to questions list', questions_path

- if can?(:destroy, @question)
p = link_to 'Delete', question_path(@question), method: :delete, data: { confirm: "Are you sure?" }
- if can?(:destroy, @question)
p = link_to 'Delete', question_path(@question), method: :delete, data: { confirm: "Are you sure?" }
19 changes: 10 additions & 9 deletions app/views/shared/_attached_links.html.slim
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
- if resource.links.first
h4 = "Links attached:"
ul
- resource.links.each do |link|
- if link.gist?
li = javascript_include_tag link.url+".js"
- else
li = link_to link.name, link.url
= link_to 'Remove', link_path(link.id), method: :delete, data: { confirm: 'Are you sure?' } if current_user&.author_of?(link.linkable)
-cache resource do
- if resource.links.first
h4 = "Links attached:"
ul
- resource.links.each do |link|
- if link.gist?
li = javascript_include_tag link.url+".js"
- else
li = link_to link.name, link.url
= link_to 'Remove', link_path(link.id), method: :delete, data: { confirm: 'Are you sure?' } if current_user&.author_of?(link.linkable)

2 changes: 2 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class Application < Rails::Application
config.active_job.queue_adapter = :sidekiq
config.autoload_paths += [config.root.join("app")]

config.cache_store = :redis_store, "redis://localhost:6379/0/cache", { expires_in: 90.minutes }

config.generators do |g|
g.test_framework :rspec,
view_specs: false,
Expand Down
4 changes: 3 additions & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
"Cache-Control" => "public, max-age=#{2.days.to_i}",
}
else
config.action_controller.perform_caching = false
config.action_controller.perform_caching = true

config.cache_store = :null_store

config.action_controller.enable_fragment_cache_logging = true
end

# Store uploaded files on the local file system (see config/storage.yml for options).
Expand Down