# frozen_string_literal: true # == Schema Information # # Table name: user_ips # # id :integer not null, primary key # ip :inet not null # uses :integer default(0), not null # created_at :datetime not null # updated_at :datetime not null # user_id :integer not null # # Indexes # # index_user_ips_on_ip_and_user_id (ip,user_id) UNIQUE # index_user_ips_on_updated_at (updated_at) # index_user_ips_on_user_id_and_updated_at (user_id,updated_at DESC) # # Foreign Keys # # fk_rails_... (user_id => users.id) ON DELETE => cascade ON UPDATE => cascade # class UserIp < ApplicationRecord FAKE_STAFF_IP = '127.0.1.1' # Intentionally not 127.0.0.1 include ActiveRecord::Sanitization::ClassMethods belongs_to :user, optional: true validates :user_id, uniqueness: { scope: :ip } # Find IPv4 addresses updated more recently than `time`. def self.recent_ipv4(time) select(:ip) .where('family(ip) = 4 AND updated_at > ?', time) end # Find IPv6 /64s updated more recently than `time`. def self.recent_ipv6(time) select('network(set_masklen(ip, 64)) as ip') .where('family(ip) = 6 AND updated_at > ?', time) end def self.record_use(user, ip) # don't try to record nil users/ips as it would fail return if user.nil? || ip.blank? ip = FAKE_STAFF_IP if user.staff? UserIp._upsert_all( [ip: ip, user_id: user.id], unique_by: [:ip, :user_id], set: 'uses = user_ips.uses + 1, updated_at = now()' ) end end