about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authoralpaca-tc <alpaca-tc@alpaca.tc>2017-05-07 23:40:57 +0900
committerEugen Rochko <eugen@zeonfederated.com>2017-05-07 16:40:57 +0200
commitca05bfaac7894285bf9ebbfeebe8c379b94eeb42 (patch)
tree4bf7da6fbdc038683f80c0ee0f3f730d259efc54 /app/models
parente4b84c7ba5bc4fa92f97aa8853d07931e460f87a (diff)
Refactor account.rb (#2881)
* Call simple query

* Refactor Account#keypair

* Replace escaped single quote

* Extract similar behavior to method

* Gather the same condition to one block

* Remove not needed receiver
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb46
1 files changed, 27 insertions, 19 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index d5b55174e..a28dc967f 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -48,12 +48,16 @@ class Account < ApplicationRecord
 
   # Local users
   has_one :user, inverse_of: :account
-  validates :username, presence: true, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, if: 'local?'
-  validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
 
-  # Local user profile validations
-  validates :display_name, length: { maximum: 30 }, if: 'local?'
-  validates :note, length: { maximum: 160 }, if: 'local?'
+  validates :username, presence: true
+  validates :username, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
+
+  # Local user validations
+  with_options if: 'local?' do
+    validates :username, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }
+    validates :display_name, length: { maximum: 30 }
+    validates :note, length: { maximum: 160 }
+  end
 
   # Timelines
   has_many :stream_entries, inverse_of: :account, dependent: :destroy
@@ -114,15 +118,15 @@ class Account < ApplicationRecord
   delegate :allowed_languages, to: :user, prefix: false, allow_nil: true
 
   def follow!(other_account)
-    active_relationships.where(target_account: other_account).first_or_create!(target_account: other_account)
+    active_relationships.find_or_create_by!(target_account: other_account)
   end
 
   def block!(other_account)
-    block_relationships.where(target_account: other_account).first_or_create!(target_account: other_account)
+    block_relationships.find_or_create_by!(target_account: other_account)
   end
 
   def mute!(other_account)
-    mute_relationships.where(target_account: other_account).first_or_create!(target_account: other_account)
+    mute_relationships.find_or_create_by!(target_account: other_account)
   end
 
   def unfollow!(other_account)
@@ -181,15 +185,15 @@ class Account < ApplicationRecord
   end
 
   def favourited?(status)
-    status.proper.favourites.where(account: self).count.positive?
+    status.proper.favourites.where(account: self).exists?
   end
 
   def reblogged?(status)
-    status.proper.reblogs.where(account: self).count.positive?
+    status.proper.reblogs.where(account: self).exists?
   end
 
   def keypair
-    private_key.nil? ? OpenSSL::PKey::RSA.new(public_key) : OpenSSL::PKey::RSA.new(private_key)
+    OpenSSL::PKey::RSA.new(private_key || public_key)
   end
 
   def subscription(webhook_url)
@@ -262,9 +266,7 @@ class Account < ApplicationRecord
     end
 
     def search_for(terms, limit = 10)
-      terms      = Arel.sql(connection.quote(terms.gsub(/['?\\:]/, ' ')))
-      textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
-      query      = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
+      textsearch, query = generate_query_for_search(terms)
 
       sql = <<-SQL.squish
         SELECT
@@ -276,13 +278,11 @@ class Account < ApplicationRecord
         LIMIT ?
       SQL
 
-      Account.find_by_sql([sql, limit])
+      find_by_sql([sql, limit])
     end
 
     def advanced_search_for(terms, account, limit = 10)
-      terms      = Arel.sql(connection.quote(terms.gsub(/['?\\:]/, ' ')))
-      textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
-      query      = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
+      textsearch, query = generate_query_for_search(terms)
 
       sql = <<-SQL.squish
         SELECT
@@ -296,7 +296,7 @@ class Account < ApplicationRecord
         LIMIT ?
       SQL
 
-      Account.find_by_sql([sql, account.id, account.id, limit])
+      find_by_sql([sql, account.id, account.id, limit])
     end
 
     def following_map(target_account_ids, account_id)
@@ -321,6 +321,14 @@ class Account < ApplicationRecord
 
     private
 
+    def generate_query_for_search(terms)
+      terms      = Arel.sql(connection.quote(terms.gsub(/['?\\:]/, ' ')))
+      textsearch = "(setweight(to_tsvector('simple', accounts.display_name), 'A') || setweight(to_tsvector('simple', accounts.username), 'B') || setweight(to_tsvector('simple', coalesce(accounts.domain, '')), 'C'))"
+      query      = "to_tsquery('simple', ''' ' || #{terms} || ' ''' || ':*')"
+
+      [textsearch, query]
+    end
+
     def follow_mapping(query, field)
       query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true }
     end