1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
class Tweet < ActiveRecord::Base
belongs_to :user
has_many :favorites, -> { order("favorites.id") }, dependent: :delete_all
has_many :retweets, -> { order("retweets.id") }, dependent: :delete_all
has_one :stolen_tweet, ->{ includes(:original) }, dependent: :delete
has_many :favoriters, -> {order("favorites.id") }, through: :favorites, source: :user
has_many :retweeters, -> { order("retweets.id") }, through: :retweets, source: :user
has_one :original, through: :stolen_tweet, source: :original
scope :recent, -> { where("tweets.tweeted_at > ?", Time.zone.now - 3.days) }
scope :reacted, -> {where("tweets.favorites_count > 0 OR tweets.retweets_count > 0") }
scope :original, -> { includes(:stolen_tweet).where(stolen_tweets: {tweet_id: nil}) }
scope :not_protected, -> { includes(:user).where(users: {protected: false}) }
scope :max_id, -> id { where("tweets.id <= ?", id.to_i) if id }
scope :since_id, -> id { where("tweets.id > ?", id.to_i) if id }
scope :page, -> page, count { offset((page - 1) * count) }
scope :order_by_id, -> { order("tweets.id DESC") }
scope :order_by_favorites, -> { order("tweets.favorites_count DESC") }
scope :order_by_retweets, -> { order("tweets.retweets_count DESC") }
scope :order_by_reactions, -> { order("COALESCE(tweets.favorites_count, 0) + COALESCE(tweets.retweets_count, 0) DESC") }
scope :of, -> user { where(user: user) if user }
scope :favorited_by, -> user { joins(:favorites).where(favorites: {user_id: user.id}) }
scope :retweeted_by, -> user { joins(:retweets).where(retweets: {user_id: user.id}) }
scope :discovered_by, -> user { joins("INNER JOIN (#{user.favorites.to_sql} UNION #{user.retweets.to_sql}) m ON m.tweet_id = tweets.id") }
# will be moved
def notify_favorite
if [50, 100, 250, 500, 1000].include? favorites.count
Aclog::Notification.reply_favs(self, favorites.count)
end
end
def self.delete_from_id(id)
begin
# counter_cache の無駄を省くために delete_all で
deleted_tweets = Tweet.delete_all(id: id)
if deleted_tweets.to_i > 0
Favorite.delete_all(tweet_id: id)
Retweet.delete_all(tweet_id: id)
else
Retweet.where(id: id).destroy_all # counter_cache
end
return id
rescue
logger.error("Unknown error while deleting tweet: #{$!}/#{$@}")
end
end
def self.from_hash(hash)
begin
t = create!(id: hash[:id],
text: hash[:text],
source: hash[:source],
tweeted_at: hash[:tweeted_at],
user_id: hash[:user_id])
return t
rescue ActiveRecord::RecordNotUnique
logger.debug("Duplicate Tweet: #{hash[:id]}")
rescue
logger.error("Unknown error while inserting tweet: #{$!}/#{$@}")
end
end
def self.list(params, options = {})
params[:page] ||= "1" if options[:force_page]
count = params[:count].to_i
count = 10 unless (1..100) === count
ret = limit(count)
if params[:page]
ret.page(params[:page].to_i, count)
else
ret.max_id(params[:max_id]).since_id(params[:since_id])
end
end
end
|