1class TrendingIp < ActiveRecord::Base |
|
2 belongs_to :petition |
|
4 validates :ip_address, presence: true |
|
5 validates :country_code, presence: true, format: { with: /\A[A-Z]{2}\z/ } |
|
6 validates :count, presence: true, numericality: { only_integer: true, greater_than: 0 } |
|
7 validates :starts_at, presence: true |
|
9 attr_readonly(:ip_address, :country_code, :count, :starts_at) |
|
11 before_validation on: :create do |
|
12 result = geoip_db.lookup(ip_address.to_s)
|
|
14 if result.found? |
|
15 self.country_code ||= result.country.iso_code |
|
16 else |
|
17 self.country_code ||= "XX" |
|
18 end |
|
19 end |
|
21 class << self |
|
22 def default_scope |
|
23 order(created_at: :desc, count: :desc) |
|
24 end |
|
26 def log!(time, ip_address, count) |
|
27 create!(ip_address: ip_address, count: count, starts_at: time) |
|
28 end |
|
30 def search(query, options = {}) |
|
31 query = query.to_s
|
|
32 page = [options[:page].to_i, 1].max |
|
34 if query.present? |
|
35 scope = where("ip_address <<= ?", query) |
|
36 else |
|
37 scope = all
|
|
38 end |
|
40 scope.paginate(page: page, per_page: 50) |
|
41 end |
|
42 end |
|
|
44 def ends_at |
45 starts_at.advance(hours: 1) |
|
46 end |
|
|
48 def window |
49 starts_at.getutc.iso8601(0) |
|
50 end |
|
52 private
|
|
|
54 def geoip_db |
55 @geoip_db ||= MaxMindDB.new(ENV.fetch('GEOIP_DB_PATH')) |
|
56 end |
|
57end |