mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Remove SearchObserver, aim is to remove all observers
rails-observers gem is mostly unmaintained and is a pain to carry forward new implementation contains significantly less magic as a bonus
This commit is contained in:
parent
31cda7b372
commit
0a78ae739d
@ -41,20 +41,26 @@ class Category < ActiveRecord::Base
|
|||||||
validate :email_in_validator
|
validate :email_in_validator
|
||||||
|
|
||||||
validate :ensure_slug
|
validate :ensure_slug
|
||||||
|
|
||||||
|
after_create :create_category_definition
|
||||||
|
|
||||||
before_save :apply_permissions
|
before_save :apply_permissions
|
||||||
before_save :downcase_email
|
before_save :downcase_email
|
||||||
before_save :downcase_name
|
before_save :downcase_name
|
||||||
after_create :create_category_definition
|
|
||||||
|
|
||||||
after_save :publish_category
|
|
||||||
after_destroy :publish_category_deletion
|
|
||||||
|
|
||||||
after_update :rename_category_definition, if: :name_changed?
|
|
||||||
|
|
||||||
after_create :delete_category_permalink
|
|
||||||
after_update :create_category_permalink, if: :slug_changed?
|
|
||||||
|
|
||||||
after_save :publish_discourse_stylesheet
|
after_save :publish_discourse_stylesheet
|
||||||
|
after_save :publish_category
|
||||||
|
after_save :reset_topic_ids_cache
|
||||||
|
after_save :clear_url_cache
|
||||||
|
after_save :index_search
|
||||||
|
|
||||||
|
after_destroy :reset_topic_ids_cache
|
||||||
|
after_destroy :publish_category_deletion
|
||||||
|
|
||||||
|
after_create :delete_category_permalink
|
||||||
|
|
||||||
|
after_update :rename_category_definition, if: :name_changed?
|
||||||
|
after_update :create_category_permalink, if: :slug_changed?
|
||||||
|
|
||||||
has_one :category_search_data
|
has_one :category_search_data
|
||||||
belongs_to :parent_category, class_name: 'Category'
|
belongs_to :parent_category, class_name: 'Category'
|
||||||
@ -65,8 +71,6 @@ class Category < ActiveRecord::Base
|
|||||||
has_many :category_tag_groups, dependent: :destroy
|
has_many :category_tag_groups, dependent: :destroy
|
||||||
has_many :tag_groups, through: :category_tag_groups
|
has_many :tag_groups, through: :category_tag_groups
|
||||||
|
|
||||||
after_save :reset_topic_ids_cache
|
|
||||||
after_destroy :reset_topic_ids_cache
|
|
||||||
|
|
||||||
scope :latest, -> { order('topic_count DESC') }
|
scope :latest, -> { order('topic_count DESC') }
|
||||||
|
|
||||||
@ -425,9 +429,7 @@ SQL
|
|||||||
|
|
||||||
@@url_cache = DistributedCache.new('category_url')
|
@@url_cache = DistributedCache.new('category_url')
|
||||||
|
|
||||||
after_save do
|
def clear_url_cache
|
||||||
# parent takes part in url calculation
|
|
||||||
# any change could invalidate multiples
|
|
||||||
@@url_cache.clear
|
@@url_cache.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -491,6 +493,10 @@ SQL
|
|||||||
DiscourseStylesheets.cache.clear
|
DiscourseStylesheets.cache.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index_search
|
||||||
|
SearchIndexer.index(self)
|
||||||
|
end
|
||||||
|
|
||||||
def self.find_by_slug(category_slug, parent_category_slug=nil)
|
def self.find_by_slug(category_slug, parent_category_slug=nil)
|
||||||
if parent_category_slug
|
if parent_category_slug
|
||||||
parent_category_id = self.where(slug: parent_category_slug, parent_category_id: nil).pluck(:id).first
|
parent_category_id = self.where(slug: parent_category_slug, parent_category_id: nil).pluck(:id).first
|
||||||
|
@ -51,6 +51,8 @@ class Post < ActiveRecord::Base
|
|||||||
|
|
||||||
validates_with ::Validators::PostValidator
|
validates_with ::Validators::PostValidator
|
||||||
|
|
||||||
|
after_save :index_search
|
||||||
|
|
||||||
# We can pass several creating options to a post via attributes
|
# We can pass several creating options to a post via attributes
|
||||||
attr_accessor :image_sizes, :quoted_post_numbers, :no_bump, :invalidate_oneboxes, :cooking_options, :skip_unique_check
|
attr_accessor :image_sizes, :quoted_post_numbers, :no_bump, :invalidate_oneboxes, :cooking_options, :skip_unique_check
|
||||||
|
|
||||||
@ -636,6 +638,10 @@ class Post < ActiveRecord::Base
|
|||||||
PostTiming.where(topic_id: topic_id, post_number: post_number, user_id: user.id).exists?
|
PostTiming.where(topic_id: topic_id, post_number: post_number, user_id: user.id).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index_search
|
||||||
|
SearchIndexer.index(self)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_quote_into_arguments(quote)
|
def parse_quote_into_arguments(quote)
|
||||||
|
@ -198,6 +198,8 @@ class Topic < ActiveRecord::Base
|
|||||||
TagUser.auto_track(topic_id: id)
|
TagUser.auto_track(topic_id: id)
|
||||||
self.tags_changed = false
|
self.tags_changed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SearchIndexer.index(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize_default_values
|
def initialize_default_values
|
||||||
|
@ -99,6 +99,7 @@ class User < ActiveRecord::Base
|
|||||||
after_save :refresh_avatar
|
after_save :refresh_avatar
|
||||||
after_save :badge_grant
|
after_save :badge_grant
|
||||||
after_save :expire_old_email_tokens
|
after_save :expire_old_email_tokens
|
||||||
|
after_save :index_search
|
||||||
|
|
||||||
before_destroy do
|
before_destroy do
|
||||||
# These tables don't have primary keys, so destroying them with activerecord is tricky:
|
# These tables don't have primary keys, so destroying them with activerecord is tricky:
|
||||||
@ -913,6 +914,10 @@ class User < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index_search
|
||||||
|
SearchIndexer.index(self)
|
||||||
|
end
|
||||||
|
|
||||||
def clear_global_notice_if_needed
|
def clear_global_notice_if_needed
|
||||||
if admin && SiteSetting.has_login_hint
|
if admin && SiteSetting.has_login_hint
|
||||||
SiteSetting.has_login_hint = false
|
SiteSetting.has_login_hint = false
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
require_dependency 'search'
|
require_dependency 'search'
|
||||||
|
|
||||||
class SearchObserver < ActiveRecord::Observer
|
class SearchIndexer
|
||||||
observe :topic, :post, :user, :category
|
|
||||||
|
def self.disable
|
||||||
|
@disabled = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.enable
|
||||||
|
@disabled = false
|
||||||
|
end
|
||||||
|
|
||||||
def self.scrub_html_for_search(html)
|
def self.scrub_html_for_search(html)
|
||||||
HtmlScrubber.scrub(html)
|
HtmlScrubber.scrub(html)
|
||||||
@ -72,17 +79,19 @@ class SearchObserver < ActiveRecord::Observer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.index(obj)
|
def self.index(obj)
|
||||||
|
return if @disabled
|
||||||
|
|
||||||
if obj.class == Post && obj.cooked_changed?
|
if obj.class == Post && obj.cooked_changed?
|
||||||
if obj.topic
|
if obj.topic
|
||||||
category_name = obj.topic.category.name if obj.topic.category
|
category_name = obj.topic.category.name if obj.topic.category
|
||||||
SearchObserver.update_posts_index(obj.id, obj.cooked, obj.topic.title, category_name)
|
SearchIndexer.update_posts_index(obj.id, obj.cooked, obj.topic.title, category_name)
|
||||||
SearchObserver.update_topics_index(obj.topic_id, obj.topic.title, obj.cooked) if obj.is_first_post?
|
SearchIndexer.update_topics_index(obj.topic_id, obj.topic.title, obj.cooked) if obj.is_first_post?
|
||||||
else
|
else
|
||||||
Rails.logger.warn("Orphan post skipped in search_observer, topic_id: #{obj.topic_id} post_id: #{obj.id} raw: #{obj.raw}")
|
Rails.logger.warn("Orphan post skipped in search_indexer, topic_id: #{obj.topic_id} post_id: #{obj.id} raw: #{obj.raw}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if obj.class == User && (obj.username_changed? || obj.name_changed?)
|
if obj.class == User && (obj.username_changed? || obj.name_changed?)
|
||||||
SearchObserver.update_users_index(obj.id, obj.username_lower || '', obj.name ? obj.name.downcase : '')
|
SearchIndexer.update_users_index(obj.id, obj.username_lower || '', obj.name ? obj.name.downcase : '')
|
||||||
end
|
end
|
||||||
|
|
||||||
if obj.class == Topic && obj.title_changed?
|
if obj.class == Topic && obj.title_changed?
|
||||||
@ -90,21 +99,17 @@ class SearchObserver < ActiveRecord::Observer
|
|||||||
post = obj.posts.find_by(post_number: 1)
|
post = obj.posts.find_by(post_number: 1)
|
||||||
if post
|
if post
|
||||||
category_name = obj.category.name if obj.category
|
category_name = obj.category.name if obj.category
|
||||||
SearchObserver.update_posts_index(post.id, post.cooked, obj.title, category_name)
|
SearchIndexer.update_posts_index(post.id, post.cooked, obj.title, category_name)
|
||||||
SearchObserver.update_topics_index(obj.id, obj.title, post.cooked)
|
SearchIndexer.update_topics_index(obj.id, obj.title, post.cooked)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if obj.class == Category && obj.name_changed?
|
if obj.class == Category && obj.name_changed?
|
||||||
SearchObserver.update_categories_index(obj.id, obj.name)
|
SearchIndexer.update_categories_index(obj.id, obj.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_save(object)
|
|
||||||
SearchObserver.index(object)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class HtmlScrubber < Nokogiri::XML::SAX::Document
|
class HtmlScrubber < Nokogiri::XML::SAX::Document
|
||||||
attr_reader :scrubbed
|
attr_reader :scrubbed
|
@ -85,7 +85,6 @@ module Discourse
|
|||||||
:user_email_observer,
|
:user_email_observer,
|
||||||
:user_action_observer,
|
:user_action_observer,
|
||||||
:post_alert_observer,
|
:post_alert_observer,
|
||||||
:search_observer
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||||
@ -169,6 +168,22 @@ module Discourse
|
|||||||
end
|
end
|
||||||
|
|
||||||
config.after_initialize do
|
config.after_initialize do
|
||||||
|
# require common dependencies that are often required by plugins
|
||||||
|
# in the past observers would load them as side-effects
|
||||||
|
# correct behavior is for plugins to require stuff they need,
|
||||||
|
# however it would be a risky and breaking change not to require here
|
||||||
|
require_dependency 'category'
|
||||||
|
require_dependency 'post'
|
||||||
|
require_dependency 'topic'
|
||||||
|
require_dependency 'user'
|
||||||
|
require_dependency 'post_action'
|
||||||
|
require_dependency 'post_revision'
|
||||||
|
require_dependency 'notification'
|
||||||
|
require_dependency 'topic_user'
|
||||||
|
require_dependency 'group'
|
||||||
|
require_dependency 'user_field'
|
||||||
|
require_dependency 'post_action_type'
|
||||||
|
|
||||||
# So open id logs somewhere sane
|
# So open id logs somewhere sane
|
||||||
OpenID::Util.logger = Rails.logger
|
OpenID::Util.logger = Rails.logger
|
||||||
if plugins = Discourse.plugins
|
if plugins = Discourse.plugins
|
||||||
|
@ -54,7 +54,7 @@ class Search
|
|||||||
posts.each do |post|
|
posts.each do |post|
|
||||||
# force indexing
|
# force indexing
|
||||||
post.cooked += " "
|
post.cooked += " "
|
||||||
SearchObserver.index(post)
|
SearchIndexer.index(post)
|
||||||
end
|
end
|
||||||
|
|
||||||
posts = Post.joins(:topic)
|
posts = Post.joins(:topic)
|
||||||
@ -67,7 +67,7 @@ class Search
|
|||||||
posts.each do |post|
|
posts.each do |post|
|
||||||
# force indexing
|
# force indexing
|
||||||
post.cooked += " "
|
post.cooked += " "
|
||||||
SearchObserver.index(post)
|
SearchIndexer.index(post)
|
||||||
end
|
end
|
||||||
|
|
||||||
nil
|
nil
|
||||||
|
@ -49,7 +49,7 @@ class Search
|
|||||||
|
|
||||||
|
|
||||||
def self.blurb_for(cooked, term=nil, blurb_length=200)
|
def self.blurb_for(cooked, term=nil, blurb_length=200)
|
||||||
cooked = SearchObserver::HtmlScrubber.scrub(cooked).squish
|
cooked = SearchIndexer::HtmlScrubber.scrub(cooked).squish
|
||||||
|
|
||||||
blurb = nil
|
blurb = nil
|
||||||
if term
|
if term
|
||||||
|
@ -18,8 +18,8 @@ def reindex_search(db=RailsMultisite::ConnectionManagement.current_db)
|
|||||||
post_number = p["post_number"].to_i
|
post_number = p["post_number"].to_i
|
||||||
topic_id = p["topic_id"].to_i
|
topic_id = p["topic_id"].to_i
|
||||||
|
|
||||||
SearchObserver.update_posts_index(post_id, cooked, title, category)
|
SearchIndexer.update_posts_index(post_id, cooked, title, category)
|
||||||
SearchObserver.update_topics_index(topic_id, title , cooked) if post_number == 1
|
SearchIndexer.update_topics_index(topic_id, title , cooked) if post_number == 1
|
||||||
|
|
||||||
putc "."
|
putc "."
|
||||||
end
|
end
|
||||||
@ -30,7 +30,7 @@ def reindex_search(db=RailsMultisite::ConnectionManagement.current_db)
|
|||||||
id = u["id"]
|
id = u["id"]
|
||||||
name = u["name"]
|
name = u["name"]
|
||||||
username = u["username"]
|
username = u["username"]
|
||||||
SearchObserver.update_users_index(id, username, name)
|
SearchIndexer.update_users_index(id, username, name)
|
||||||
|
|
||||||
putc "."
|
putc "."
|
||||||
end
|
end
|
||||||
@ -41,7 +41,7 @@ def reindex_search(db=RailsMultisite::ConnectionManagement.current_db)
|
|||||||
Category.exec_sql("select id, name from categories").each do |c|
|
Category.exec_sql("select id, name from categories").each do |c|
|
||||||
id = c["id"]
|
id = c["id"]
|
||||||
name = c["name"]
|
name = c["name"]
|
||||||
SearchObserver.update_categories_index(id, name)
|
SearchIndexer.update_categories_index(id, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
puts
|
puts
|
||||||
|
@ -10,7 +10,7 @@ describe Search do
|
|||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
ActiveRecord::Base.observers.enable :search_observer
|
SearchIndexer.enable
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'post indexing observer' do
|
context 'post indexing observer' do
|
||||||
|
@ -5,7 +5,7 @@ describe SearchController do
|
|||||||
context "integration" do
|
context "integration" do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
ActiveRecord::Base.observers.enable :search_observer
|
SearchIndexer.enable
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can search correctly" do
|
it "can search correctly" do
|
||||||
|
@ -1331,7 +1331,7 @@ describe UsersController do
|
|||||||
let(:user) { Fabricate :user, username: "joecabot", name: "Lawrence Tierney" }
|
let(:user) { Fabricate :user, username: "joecabot", name: "Lawrence Tierney" }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
ActiveRecord::Base.observers.enable :all
|
SearchIndexer.enable
|
||||||
Fabricate :post, user: user, topic: topic
|
Fabricate :post, user: user, topic: topic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ describe Topic do
|
|||||||
|
|
||||||
context 'with a similar topic' do
|
context 'with a similar topic' do
|
||||||
let!(:topic) {
|
let!(:topic) {
|
||||||
ActiveRecord::Base.observers.enable :search_observer
|
SearchIndexer.enable
|
||||||
post = create_post(title: "Evil trout is the dude who posted this topic")
|
post = create_post(title: "Evil trout is the dude who posted this topic")
|
||||||
post.topic
|
post.topic
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ describe UserSearch do
|
|||||||
let(:staged) { Fabricate :staged }
|
let(:staged) { Fabricate :staged }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
ActiveRecord::Base.observers.enable :all
|
SearchIndexer.enable
|
||||||
|
|
||||||
Fabricate :post, user: user1, topic: topic
|
Fabricate :post, user: user1, topic: topic
|
||||||
Fabricate :post, user: user2, topic: topic2
|
Fabricate :post, user: user2, topic: topic2
|
||||||
|
@ -107,6 +107,8 @@ Spork.prefork do
|
|||||||
# disable all observers, enable as needed during specs
|
# disable all observers, enable as needed during specs
|
||||||
#
|
#
|
||||||
ActiveRecord::Base.observers.disable :all
|
ActiveRecord::Base.observers.disable :all
|
||||||
|
SearchIndexer.disable
|
||||||
|
|
||||||
SiteSetting.provider.all.each do |setting|
|
SiteSetting.provider.all.each do |setting|
|
||||||
SiteSetting.remove_override!(setting.name)
|
SiteSetting.remove_override!(setting.name)
|
||||||
end
|
end
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe SearchObserver do
|
describe SearchIndexer do
|
||||||
|
|
||||||
it 'correctly indexes chinese' do
|
it 'correctly indexes chinese' do
|
||||||
SiteSetting.default_locale = 'zh_CN'
|
SiteSetting.default_locale = 'zh_CN'
|
||||||
data = "你好世界"
|
data = "你好世界"
|
||||||
expect(data.split(" ").length).to eq(1)
|
expect(data.split(" ").length).to eq(1)
|
||||||
|
|
||||||
SearchObserver.update_posts_index(99, "你好世界", "", nil)
|
SearchIndexer.update_posts_index(99, "你好世界", "", nil)
|
||||||
|
|
||||||
raw_data = PostSearchData.where(post_id: 99).pluck(:raw_data)[0]
|
raw_data = PostSearchData.where(post_id: 99).pluck(:raw_data)[0]
|
||||||
expect(raw_data.split(' ').length).to eq(2)
|
expect(raw_data.split(' ').length).to eq(2)
|
||||||
@ -16,13 +16,13 @@ describe SearchObserver do
|
|||||||
it 'correctly indexes a post' do
|
it 'correctly indexes a post' do
|
||||||
data = "<a>This</a> is a test"
|
data = "<a>This</a> is a test"
|
||||||
|
|
||||||
SearchObserver.update_posts_index(99, data, "", nil)
|
SearchIndexer.update_posts_index(99, data, "", nil)
|
||||||
|
|
||||||
raw_data, locale = PostSearchData.where(post_id: 99).pluck(:raw_data, :locale)[0]
|
raw_data, locale = PostSearchData.where(post_id: 99).pluck(:raw_data, :locale)[0]
|
||||||
expect(raw_data).to eq("This is a test")
|
expect(raw_data).to eq("This is a test")
|
||||||
expect(locale).to eq("en")
|
expect(locale).to eq("en")
|
||||||
|
|
||||||
SearchObserver.update_posts_index(99, "tester", "", nil)
|
SearchIndexer.update_posts_index(99, "tester", "", nil)
|
||||||
|
|
||||||
raw_data = PostSearchData.where(post_id: 99).pluck(:raw_data)[0]
|
raw_data = PostSearchData.where(post_id: 99).pluck(:raw_data)[0]
|
||||||
expect(raw_data).to eq("tester")
|
expect(raw_data).to eq("tester")
|
Loading…
Reference in New Issue
Block a user