Merge pull request #75 from srgpqt/master

replace some raw sql with database-agnostic activerecord queries
This commit is contained in:
joshua stein 2013-12-30 13:47:53 -08:00
commit 8a76402c1b
6 changed files with 72 additions and 69 deletions

View File

@ -136,13 +136,23 @@ private
def _find_stories_for_user_and_tag_and_newest_and_by_user(user, tag = nil,
newest = false, by_user = nil)
conds = [ "is_expired = 0 " ]
stories = Story.where(:is_expired => false)
if user && !(newest || by_user)
# exclude downvoted items
conds[0] << "AND stories.id NOT IN (SELECT story_id FROM votes " <<
"WHERE user_id = ? AND vote < 0 AND comment_id IS NULL) "
conds.push user.id
stories = stories.where(
Story.arel_table[:id].not_in(
Vote.arel_table.where(
Vote.arel_table[:user_id].eq(user.id)
).where(
Vote.arel_table[:vote].lt(0)
).where(
Vote.arel_table[:comment_id].eq(nil)
).project(
Vote.arel_table[:story_id]
)
)
)
end
filtered_tag_ids = []
@ -155,22 +165,30 @@ private
end
if tag
conds[0] << "AND stories.id IN (SELECT taggings.story_id FROM " <<
"taggings WHERE taggings.tag_id = ?)"
conds.push tag.id
stories = stories.where(
Story.arel_table[:id].in(
Tagging.arel_table.where(
Tagging.arel_table[:tag_id].eq(tag.id)
).project(
Tagging.arel_table[:story_id]
)
)
)
elsif by_user
conds[0] << "AND stories.user_id = ?"
conds.push by_user
stories = stories.where(:user_id => by_user)
elsif filtered_tag_ids.any?
conds[0] += " AND stories.id NOT IN (SELECT taggings.story_id " <<
"FROM taggings WHERE taggings.tag_id IN (" <<
filtered_tag_ids.map{|t| "?" }.join(",") << "))"
conds += filtered_tag_ids
stories = stories.where(
Story.arel_table[:id].not_in(
Tagging.arel_table.where(
Tagging.arel_table[:tag_id].in(filtered_tag_ids)
).project(
Tagging.arel_table[:story_id]
)
)
)
end
stories = Story.where(
*conds
).includes(
stories = stories.includes(
:user, :taggings => :tag
).limit(
STORIES_PER_PAGE + 1

View File

@ -405,8 +405,7 @@ class Story < ActiveRecord::Base
end
def recalculate_hotness!
Story.connection.execute("UPDATE #{Story.table_name} SET " <<
"hotness = '#{self.calculated_hotness}' WHERE id = #{self.id.to_i}")
update_column :hotness, calculated_hotness
end
def update_comment_count!

View File

@ -1,6 +1,8 @@
class Tag < ActiveRecord::Base
has_many :taggings,
:dependent => :delete_all
has_many :stories,
:through => :taggings
attr_accessor :filtered_count

View File

@ -1,6 +1,4 @@
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :story
attr_accessible nil
belongs_to :tag, :inverse_of => :taggings
belongs_to :story, :inverse_of => :taggings
end

View File

@ -118,22 +118,19 @@ class User < ActiveRecord::Base
end
def most_common_story_tag
tag_id = Tagging.connection.select_one("SELECT tag_id, " <<
"COUNT(taggings.id) AS tag_count FROM taggings LEFT OUTER JOIN " <<
"stories ON stories.id = taggings.story_id WHERE stories.user_id = " <<
"#{q(self.id)} GROUP BY tag_id ORDER BY tag_count DESC LIMIT 1")
if tag_id && tag_id["tag_id"]
Tag.where(:id => tag_id["tag_id"]).first
else
nil
end
Tag.joins(
:stories
).where(
:stories => { :user_id => self.id }
).group(
Tag.arel_table[:id]
).order(
'COUNT(*) desc'
).first
end
def recent_threads(amount)
Comment.connection.select_all("SELECT DISTINCT " +
"thread_id FROM comments WHERE user_id = #{q(self.id)} ORDER BY " +
"created_at DESC LIMIT #{q(amount)}").map{|r| r.values.first }
self.comments.order('created_at desc').limit(amount).uniq.pluck(:thread_id)
end
def stories_submitted_count

View File

@ -49,45 +49,34 @@ class Vote < ActiveRecord::Base
end
def self.story_votes_by_user_for_story_ids_hash(user_id, story_ids)
if !story_ids.any?
return {}
if story_ids.empty?
{}
else
votes = self.where(
:user_id => user_id,
:comment_id => nil,
:story_id => story_ids,
)
votes.inject({}) do |memo, v|
memo[v.story_id] = { :vote => v.vote, :reason => v.reason }
memo
end
end
votes = {}
cond = [ "user_id = ? AND comment_id IS NULL AND story_id IN (", user_id ]
story_ids.each_with_index do |s,x|
cond.push s
cond[0] += (x == 0 ? "" : ",") + "?"
end
cond[0] += ")"
Vote.where(*cond).each do |v|
votes[v.story_id] = { :vote => v.vote, :reason => v.reason }
end
votes
end
def self.comment_votes_by_user_for_comment_ids_hash(user_id, comment_ids)
if !comment_ids.any?
return {}
if comment_ids.empty?
{}
else
votes = self.where(
:user_id => user_id,
:comment_id => comment_ids,
)
votes.inject({}) do |memo, v|
memo[v.comment_id] = { :vote => v.vote, :reason => v.reason }
memo
end
end
votes = {}
cond = [ "user_id = ? AND comment_id IN (", user_id ]
comment_ids.each_with_index do |c,x|
cond.push c
cond[0] += (x == 0 ? "" : ",") + "?"
end
cond[0] += ")"
Vote.where(*cond).each do |v|
votes[v.comment_id] = { :vote => v.vote, :reason => v.reason }
end
votes
end
def self.vote_thusly_on_story_or_comment_for_user_because(vote, story_id,