From 62292797eccc5bcf47abae9f4daaa2c186660644 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 4 Nov 2016 19:12:59 +0100 Subject: [PATCH] Adding hashtag model --- app/controllers/api/v1/accounts_controller.rb | 4 ++-- app/controllers/api/v1/statuses_controller.rb | 4 ++-- app/lib/formatter.rb | 12 ++++++++++++ app/models/account.rb | 6 +++--- app/models/status.rb | 8 ++++++++ app/models/tag.rb | 5 +++++ app/models/user.rb | 2 +- db/migrate/20161104173623_create_tags.rb | 11 +++++++++++ db/schema.rb | 9 ++++++++- spec/fabricators/tag_fabricator.rb | 3 +++ spec/models/tag_spec.rb | 5 +++++ 11 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 app/models/tag.rb create mode 100644 db/migrate/20161104173623_create_tags.rb create mode 100644 spec/fabricators/tag_fabricator.rb create mode 100644 spec/models/tag_spec.rb diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 715b9085c..bb06ddac9 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -14,12 +14,12 @@ class Api::V1::AccountsController < ApiController end def following - @accounts = @account.following.limit(40) + @accounts = @account.following.with_counters.limit(40) render action: :index end def followers - @accounts = @account.followers.limit(40) + @accounts = @account.followers.with_counters.limit(40) render action: :index end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index a87e1528d..b05a27ef4 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -15,12 +15,12 @@ class Api::V1::StatusesController < ApiController end def reblogged_by - @accounts = @status.reblogs.includes(:account).limit(40).map(&:account) + @accounts = @status.reblogged_by(40) render action: :accounts end def favourited_by - @accounts = @status.favourites.includes(:account).limit(40).map(&:account) + @accounts = @status.favourited_by(40) render action: :accounts end diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 60bc3733e..d8d5424fd 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -14,6 +14,7 @@ class Formatter html = simple_format(html, sanitize: false) html = link_urls(html) html = link_mentions(html, status.mentions) + html = link_hashtags(html) html.html_safe end @@ -43,6 +44,17 @@ class Formatter end end + def link_hashtags(html) + html.gsub(Tag::HASHTAG_RE) do |match| + hashtag_html(match) + end + end + + def hashtag_html(match) + prefix, affix = match.split('#') + "#{prefix}##{affix}" + end + def mention_html(match, account) "#{match.split('@').first}@#{account.username}" end diff --git a/app/models/account.rb b/app/models/account.rb index 0a6ba182b..9999f05dd 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -33,12 +33,12 @@ class Account < ApplicationRecord has_many :active_relationships, class_name: 'Follow', foreign_key: 'account_id', dependent: :destroy has_many :passive_relationships, class_name: 'Follow', foreign_key: 'target_account_id', dependent: :destroy - has_many :following, -> { order('follows.created_at desc') }, through: :active_relationships, source: :target_account - has_many :followers, -> { order('follows.created_at desc') }, through: :passive_relationships, source: :account + has_many :following, -> { order('follows.id desc') }, through: :active_relationships, source: :target_account + has_many :followers, -> { order('follows.id desc') }, through: :passive_relationships, source: :account # Block relationships has_many :block_relationships, class_name: 'Block', foreign_key: 'account_id', dependent: :destroy - has_many :blocking, -> { order('blocks.created_at desc') }, through: :block_relationships, source: :target_account + has_many :blocking, -> { order('blocks.id desc') }, through: :block_relationships, source: :target_account has_many :media_attachments, dependent: :destroy diff --git a/app/models/status.rb b/app/models/status.rb index 1cd56c97b..c26e73d71 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -77,6 +77,14 @@ class Status < ApplicationRecord ids.map { |id| statuses[id].first } end + def reblogged_by(limit) + Account.where(id: reblogs.limit(limit).pluck(:account_id)).with_counters + end + + def favourited_by(limit) + Account.where(id: favourites.limit(limit).pluck(:account_id)).with_counters + end + def self.as_home_timeline(account) where(account: [account] + account.following).with_includes.with_counters end diff --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100644 index 000000000..a25785e08 --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,5 @@ +class Tag < ApplicationRecord + HASHTAG_RE = /[?:^|\s|\.|>]#([[:word:]_]+)/i + + validates :name, presence: true, uniqueness: true +end diff --git a/app/models/user.rb b/app/models/user.rb index bd5512a31..de3521989 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,7 +7,7 @@ class User < ApplicationRecord validates :account, presence: true scope :prolific, -> { joins('inner join statuses on statuses.account_id = users.account_id').select('users.*, count(statuses.id) as statuses_count').group('users.id').order('statuses_count desc') } - scope :recent, -> { order('created_at desc') } + scope :recent, -> { order('id desc') } scope :admins, -> { where(admin: true) } has_settings do |s| diff --git a/db/migrate/20161104173623_create_tags.rb b/db/migrate/20161104173623_create_tags.rb new file mode 100644 index 000000000..d6831ff8f --- /dev/null +++ b/db/migrate/20161104173623_create_tags.rb @@ -0,0 +1,11 @@ +class CreateTags < ActiveRecord::Migration[5.0] + def change + create_table :tags do |t| + t.string :name, null: false, default: '' + + t.timestamps + end + + add_index :tags, :name, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 0af5a6395..3d0182ba9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161027172456) do +ActiveRecord::Schema.define(version: 20161104173623) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -170,6 +170,13 @@ ActiveRecord::Schema.define(version: 20161027172456) do t.index ["activity_id", "activity_type"], name: "index_stream_entries_on_activity_id_and_activity_type", using: :btree end + create_table "tags", force: :cascade do |t| + t.string "name", default: "", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_tags_on_name", unique: true, using: :btree + end + create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.integer "account_id", null: false diff --git a/spec/fabricators/tag_fabricator.rb b/spec/fabricators/tag_fabricator.rb new file mode 100644 index 000000000..d83040990 --- /dev/null +++ b/spec/fabricators/tag_fabricator.rb @@ -0,0 +1,3 @@ +Fabricator(:tag) do + name "MyString" +end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb new file mode 100644 index 000000000..0d0fcb057 --- /dev/null +++ b/spec/models/tag_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Tag, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end