Permalink
Browse files

fix sql join of user's votes

An inner join only returns the comments the user has voted on (not useful for
the Unread page in particular). A left join on comment_id or user_id returns
duplicate rows (any 'outer apply' is nonstandard). So this just subselects it.
  • Loading branch information...
pushcx committed Feb 1, 2018
1 parent b220c0d commit 0b5567629961df60686e7c807930b796ad2f38dc
@@ -47,6 +47,7 @@ def unread
# with the current user's vote added by StoriesController.load_user_votes
def apply_current_vote
@replies.each do |r|
next unless r.current_vote_vote.present?
r.comment.current_vote = {
vote: r.current_vote_vote,
reason: r.current_vote_reason.to_s
@@ -0,0 +1,5 @@
class UpdateReplyingCommentsToVersion5 < ActiveRecord::Migration[5.0]
def change
update_view :replying_comments, version: 5, revert_to_version: 4
end
end
View
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180201041055) do
ActiveRecord::Schema.define(version: 20180201172618) do
create_table "comments", id: :integer, unsigned: true, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t|
t.datetime "created_at", null: false
@@ -248,7 +248,7 @@
create_view "replying_comments", sql_definition: <<-SQL
select `lobsters`.`read_ribbons`.`user_id` AS `user_id`,`lobsters`.`comments`.`id` AS `comment_id`,`lobsters`.`read_ribbons`.`story_id` AS `story_id`,`lobsters`.`comments`.`parent_comment_id` AS `parent_comment_id`,`lobsters`.`comments`.`created_at` AS `comment_created_at`,`parent_comments`.`user_id` AS `parent_comment_author_id`,`lobsters`.`comments`.`user_id` AS `comment_author_id`,`lobsters`.`stories`.`user_id` AS `story_author_id`,(`lobsters`.`read_ribbons`.`updated_at` < `lobsters`.`comments`.`created_at`) AS `is_unread`,`lobsters`.`votes`.`vote` AS `current_vote_vote`,`lobsters`.`votes`.`reason` AS `current_vote_reason` from ((((`lobsters`.`read_ribbons` join `lobsters`.`comments` on((`lobsters`.`comments`.`story_id` = `lobsters`.`read_ribbons`.`story_id`))) join `lobsters`.`votes` on((`lobsters`.`votes`.`comment_id` = `lobsters`.`comments`.`id`))) join `lobsters`.`stories` on((`lobsters`.`stories`.`id` = `lobsters`.`comments`.`story_id`))) left join `lobsters`.`comments` `parent_comments` on((`parent_comments`.`id` = `lobsters`.`comments`.`parent_comment_id`))) where ((`lobsters`.`read_ribbons`.`is_following` = 1) and (`lobsters`.`comments`.`user_id` <> `lobsters`.`read_ribbons`.`user_id`) and (`lobsters`.`votes`.`user_id` = `lobsters`.`read_ribbons`.`user_id`) and ((`parent_comments`.`user_id` = `lobsters`.`read_ribbons`.`user_id`) or (isnull(`parent_comments`.`user_id`) and (`lobsters`.`stories`.`user_id` = `lobsters`.`read_ribbons`.`user_id`))) and ((`lobsters`.`comments`.`upvotes` - `lobsters`.`comments`.`downvotes`) >= 0) and (isnull(`parent_comments`.`id`) or ((`parent_comments`.`upvotes` - `parent_comments`.`downvotes`) >= 0)))
select `lobsters`.`read_ribbons`.`user_id` AS `user_id`,`lobsters`.`comments`.`id` AS `comment_id`,`lobsters`.`read_ribbons`.`story_id` AS `story_id`,`lobsters`.`comments`.`parent_comment_id` AS `parent_comment_id`,`lobsters`.`comments`.`created_at` AS `comment_created_at`,`parent_comments`.`user_id` AS `parent_comment_author_id`,`lobsters`.`comments`.`user_id` AS `comment_author_id`,`lobsters`.`stories`.`user_id` AS `story_author_id`,(`lobsters`.`read_ribbons`.`updated_at` < `lobsters`.`comments`.`created_at`) AS `is_unread`,(select `lobsters`.`votes`.`vote` from `lobsters`.`votes` where ((`lobsters`.`votes`.`user_id` = `lobsters`.`read_ribbons`.`user_id`) and (`lobsters`.`votes`.`comment_id` = `lobsters`.`comments`.`id`))) AS `current_vote_vote`,(select `lobsters`.`votes`.`reason` from `lobsters`.`votes` where ((`lobsters`.`votes`.`user_id` = `lobsters`.`read_ribbons`.`user_id`) and (`lobsters`.`votes`.`comment_id` = `lobsters`.`comments`.`id`))) AS `current_vote_reason` from (((`lobsters`.`read_ribbons` join `lobsters`.`comments` on((`lobsters`.`comments`.`story_id` = `lobsters`.`read_ribbons`.`story_id`))) join `lobsters`.`stories` on((`lobsters`.`stories`.`id` = `lobsters`.`comments`.`story_id`))) left join `lobsters`.`comments` `parent_comments` on((`parent_comments`.`id` = `lobsters`.`comments`.`parent_comment_id`))) where ((`lobsters`.`read_ribbons`.`is_following` = 1) and (`lobsters`.`comments`.`user_id` <> `lobsters`.`read_ribbons`.`user_id`) and ((`parent_comments`.`user_id` = `lobsters`.`read_ribbons`.`user_id`) or (isnull(`parent_comments`.`user_id`) and (`lobsters`.`stories`.`user_id` = `lobsters`.`read_ribbons`.`user_id`))) and ((`lobsters`.`comments`.`upvotes` - `lobsters`.`comments`.`downvotes`) >= 0) and (isnull(`parent_comments`.`id`) or ((`parent_comments`.`upvotes` - `parent_comments`.`downvotes`) >= 0)))
SQL
end
@@ -0,0 +1,33 @@
SELECT
read_ribbons.user_id,
comments.id as comment_id,
read_ribbons.story_id as story_id,
comments.parent_comment_id,
comments.created_at as comment_created_at,
parent_comments.user_id as parent_comment_author_id,
comments.user_id as comment_author_id,
stories.user_id as story_author_id,
(read_ribbons.updated_at < comments.created_at) as is_unread,
(select votes.vote from votes where votes.user_id = read_ribbons.user_id and votes.comment_id = comments.id) as current_vote_vote,
(select votes.reason from votes where votes.user_id = read_ribbons.user_id and votes.comment_id = comments.id) as current_vote_reason
FROM
read_ribbons
JOIN
comments ON comments.story_id = read_ribbons.story_id
JOIN
stories ON stories.id = comments.story_id
LEFT JOIN
comments parent_comments ON parent_comments.id = comments.parent_comment_id
WHERE
read_ribbons.is_following = 1
AND comments.user_id != read_ribbons.user_id
AND
(parent_comments.user_id = read_ribbons.user_id
OR (parent_comments.user_id IS NULL
AND stories.user_id = read_ribbons.user_id))
AND (comments.upvotes - comments.downvotes) >= 0
AND (
parent_comments.id IS NULL
OR (parent_comments.upvotes - parent_comments.downvotes) >= 0
)
;

0 comments on commit 0b55676

Please sign in to comment.