| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  | # frozen_string_literal: true | 
					
						
							| 
									
										
										
										
											2017-05-02 09:14:47 +09:00
										 |  |  | # == Schema Information | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Table name: tags | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2018-04-23 18:29:17 +09:00
										 |  |  | #  id         :bigint(8)        not null, primary key | 
					
						
							| 
									
										
										
										
											2017-05-02 09:14:47 +09:00
										 |  |  | #  name       :string           default(""), not null | 
					
						
							|  |  |  | #  created_at :datetime         not null | 
					
						
							|  |  |  | #  updated_at :datetime         not null | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-04 19:12:59 +01:00
										 |  |  | class Tag < ApplicationRecord | 
					
						
							| 
									
										
										
										
											2016-11-05 15:20:05 +01:00
										 |  |  |   has_and_belongs_to_many :statuses | 
					
						
							| 
									
										
										
										
											2018-12-06 17:36:11 +01:00
										 |  |  |   has_and_belongs_to_many :accounts | 
					
						
							| 
									
										
										
										
											2018-12-08 01:32:26 +01:00
										 |  |  |   has_and_belongs_to_many :sample_accounts, -> { searchable.discoverable.popular.limit(3) }, class_name: 'Account' | 
					
						
							| 
									
										
										
										
											2018-12-06 17:36:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-04 04:25:59 +01:00
										 |  |  |   has_many :featured_tags, dependent: :destroy, inverse_of: :tag | 
					
						
							| 
									
										
										
										
											2018-12-06 17:36:11 +01:00
										 |  |  |   has_one :account_tag_stat, dependent: :destroy | 
					
						
							| 
									
										
										
										
											2016-11-05 15:20:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-11 14:55:49 +01:00
										 |  |  |   HASHTAG_NAME_RE = '[[:word:]_]*[[:alpha:]_·][[:word:]_]*' | 
					
						
							| 
									
										
										
										
											2017-07-14 18:02:49 +09:00
										 |  |  |   HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_RE})/i | 
					
						
							| 
									
										
										
										
											2016-11-04 19:12:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-14 18:02:49 +09:00
										 |  |  |   validates :name, presence: true, uniqueness: true, format: { with: /\A#{HASHTAG_NAME_RE}\z/i } | 
					
						
							| 
									
										
										
										
											2016-11-05 15:20:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-08 01:32:26 +01:00
										 |  |  |   scope :discoverable, -> { joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).where(account_tag_stats: { hidden: false }).order(Arel.sql('account_tag_stats.accounts_count desc')) } | 
					
						
							| 
									
										
										
										
											2018-12-06 17:36:11 +01:00
										 |  |  |   scope :hidden, -> { where(account_tag_stats: { hidden: true }) } | 
					
						
							| 
									
										
										
										
											2019-02-04 04:25:59 +01:00
										 |  |  |   scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) } | 
					
						
							| 
									
										
										
										
											2018-12-06 17:36:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   delegate :accounts_count, | 
					
						
							|  |  |  |            :accounts_count=, | 
					
						
							|  |  |  |            :increment_count!, | 
					
						
							|  |  |  |            :decrement_count!, | 
					
						
							|  |  |  |            :hidden?, | 
					
						
							|  |  |  |            to: :account_tag_stat | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   after_save :save_account_tag_stat | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def account_tag_stat | 
					
						
							|  |  |  |     super || build_account_tag_stat | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-08 01:32:26 +01:00
										 |  |  |   def cached_sample_accounts | 
					
						
							|  |  |  |     Rails.cache.fetch("#{cache_key}/sample_accounts", expires_in: 12.hours) { sample_accounts } | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-05 15:20:05 +01:00
										 |  |  |   def to_param | 
					
						
							|  |  |  |     name | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2017-03-22 02:32:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-27 21:45:30 +02:00
										 |  |  |   def history | 
					
						
							|  |  |  |     days = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     7.times do |i| | 
					
						
							|  |  |  |       day = i.days.ago.beginning_of_day.to_i | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       days << { | 
					
						
							|  |  |  |         day: day.to_s, | 
					
						
							|  |  |  |         uses: Redis.current.get("activity:tags:#{id}:#{day}") || '0', | 
					
						
							|  |  |  |         accounts: Redis.current.pfcount("activity:tags:#{id}:#{day}:accounts").to_s, | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     days | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-22 02:32:27 +01:00
										 |  |  |   class << self | 
					
						
							| 
									
										
										
											
												Add type, limit, offset, min_id, max_id, account_id to search API (#10091)
* Add type, limit, offset, min_id, max_id, account_id to search API
Fix #8939
* Make the offset work on accounts and hashtags search as well
* Assure brakeman we are not doing mass assignment here
* Do not allow paginating unless a type is chosen
* Fix search query and index id field on statuses instead of created_at
											
										 
											2019-02-26 15:21:36 +01:00
										 |  |  |     def search_for(term, limit = 5, offset = 0) | 
					
						
							| 
									
										
										
										
											2017-12-10 19:35:46 +01:00
										 |  |  |       pattern = sanitize_sql_like(term.strip) + '%' | 
					
						
							| 
									
										
										
											
												Add type, limit, offset, min_id, max_id, account_id to search API (#10091)
* Add type, limit, offset, min_id, max_id, account_id to search API
Fix #8939
* Make the offset work on accounts and hashtags search as well
* Assure brakeman we are not doing mass assignment here
* Do not allow paginating unless a type is chosen
* Fix search query and index id field on statuses instead of created_at
											
										 
											2019-02-26 15:21:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Tag.where('lower(name) like lower(?)', pattern) | 
					
						
							|  |  |  |          .order(:name) | 
					
						
							|  |  |  |          .limit(limit) | 
					
						
							|  |  |  |          .offset(offset) | 
					
						
							| 
									
										
										
										
											2017-03-22 02:32:27 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2019-03-13 13:02:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def find_normalized(name) | 
					
						
							|  |  |  |       find_by(name: name.mb_chars.downcase.to_s) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def find_normalized!(name) | 
					
						
							|  |  |  |       find_normalized(name) || raise(ActiveRecord::RecordNotFound) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-03-22 02:32:27 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-12-06 17:36:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def save_account_tag_stat | 
					
						
							|  |  |  |     return unless account_tag_stat&.changed? | 
					
						
							|  |  |  |     account_tag_stat.save | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-11-04 19:12:59 +01:00
										 |  |  | end |