mirror of
https://github.com/discourse/discourse.git
synced 2025-01-18 21:02:48 +08:00
remove acts_as_paranoid, use .trash! , .recover! and .with_deleted as needed
makes upgrading to rails 4 possible
This commit is contained in:
parent
a71a15913c
commit
e9fc272db7
1
Gemfile
1
Gemfile
|
@ -15,7 +15,6 @@ gem 'simple_handlebars_rails', path: 'vendor/gems/simple_handlebars_rails'
|
||||||
|
|
||||||
gem 'redcarpet', require: false
|
gem 'redcarpet', require: false
|
||||||
gem 'activerecord-postgres-hstore'
|
gem 'activerecord-postgres-hstore'
|
||||||
gem 'acts_as_paranoid'
|
|
||||||
gem 'active_attr' # until we get ActiveModel::Model with Rails 4
|
gem 'active_attr' # until we get ActiveModel::Model with Rails 4
|
||||||
gem 'airbrake', '3.1.2', require: false # errbit is broken with 3.1.3 for now
|
gem 'airbrake', '3.1.2', require: false # errbit is broken with 3.1.3 for now
|
||||||
gem 'clockwork', require: false
|
gem 'clockwork', require: false
|
||||||
|
|
|
@ -120,8 +120,6 @@ GEM
|
||||||
activesupport (3.2.12)
|
activesupport (3.2.12)
|
||||||
i18n (~> 0.6)
|
i18n (~> 0.6)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
acts_as_paranoid (0.4.1)
|
|
||||||
activerecord (~> 3.2)
|
|
||||||
airbrake (3.1.2)
|
airbrake (3.1.2)
|
||||||
activesupport
|
activesupport
|
||||||
builder
|
builder
|
||||||
|
@ -448,7 +446,6 @@ DEPENDENCIES
|
||||||
active_attr
|
active_attr
|
||||||
active_model_serializers!
|
active_model_serializers!
|
||||||
activerecord-postgres-hstore
|
activerecord-postgres-hstore
|
||||||
acts_as_paranoid
|
|
||||||
airbrake (= 3.1.2)
|
airbrake (= 3.1.2)
|
||||||
barber (= 0.3.0)
|
barber (= 0.3.0)
|
||||||
better_errors
|
better_errors
|
||||||
|
|
|
@ -33,7 +33,7 @@ class InvitesController < ApplicationController
|
||||||
|
|
||||||
invite = Invite.where(invited_by_id: current_user.id, email: params[:email]).first
|
invite = Invite.where(invited_by_id: current_user.id, email: params[:email]).first
|
||||||
raise Discourse::InvalidParameters.new(:email) if invite.blank?
|
raise Discourse::InvalidParameters.new(:email) if invite.blank?
|
||||||
invite.destroy
|
invite.trash!
|
||||||
|
|
||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -128,7 +128,7 @@ class PostsController < ApplicationController
|
||||||
def recover
|
def recover
|
||||||
post = find_post_from_params
|
post = find_post_from_params
|
||||||
guardian.ensure_can_recover_post!(post)
|
guardian.ensure_can_recover_post!(post)
|
||||||
post.recover
|
post.recover!
|
||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ class TopicsController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
topic = Topic.where(id: params[:id]).first
|
topic = Topic.where(id: params[:id]).first
|
||||||
guardian.ensure_can_delete!(topic)
|
guardian.ensure_can_delete!(topic)
|
||||||
topic.destroy
|
topic.trash!
|
||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
require_dependency 'trashable'
|
||||||
|
|
||||||
class Invite < ActiveRecord::Base
|
class Invite < ActiveRecord::Base
|
||||||
|
include Trashable
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :topic
|
belongs_to :topic
|
||||||
|
@ -9,8 +12,6 @@ class Invite < ActiveRecord::Base
|
||||||
validates_presence_of :email
|
validates_presence_of :email
|
||||||
validates_presence_of :invited_by_id
|
validates_presence_of :invited_by_id
|
||||||
|
|
||||||
acts_as_paranoid
|
|
||||||
|
|
||||||
before_create do
|
before_create do
|
||||||
self.invite_key ||= SecureRandom.hex
|
self.invite_key ||= SecureRandom.hex
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,19 +3,19 @@ require_dependency 'pretty_text'
|
||||||
require_dependency 'rate_limiter'
|
require_dependency 'rate_limiter'
|
||||||
require_dependency 'post_revisor'
|
require_dependency 'post_revisor'
|
||||||
require_dependency 'enum'
|
require_dependency 'enum'
|
||||||
|
require_dependency 'trashable'
|
||||||
|
|
||||||
require 'archetype'
|
require 'archetype'
|
||||||
require 'digest/sha1'
|
require 'digest/sha1'
|
||||||
|
|
||||||
class Post < ActiveRecord::Base
|
class Post < ActiveRecord::Base
|
||||||
include RateLimiter::OnCreateRecord
|
include RateLimiter::OnCreateRecord
|
||||||
|
include Trashable
|
||||||
|
|
||||||
versioned if: :raw_changed?
|
versioned if: :raw_changed?
|
||||||
|
|
||||||
rate_limit
|
rate_limit
|
||||||
acts_as_paranoid
|
|
||||||
|
|
||||||
after_recover :update_flagged_posts_count
|
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :topic, counter_cache: :posts_count
|
belongs_to :topic, counter_cache: :posts_count
|
||||||
|
@ -52,6 +52,11 @@ class Post < ActiveRecord::Base
|
||||||
@types ||= Enum.new(:regular, :moderator_action)
|
@types ||= Enum.new(:regular, :moderator_action)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def recover!
|
||||||
|
super
|
||||||
|
update_flagged_posts_count
|
||||||
|
end
|
||||||
|
|
||||||
def raw_quality
|
def raw_quality
|
||||||
sentinel = TextSentinel.body_sentinel(raw)
|
sentinel = TextSentinel.body_sentinel(raw)
|
||||||
errors.add(:raw, I18n.t(:is_invalid)) unless sentinel.valid?
|
errors.add(:raw, I18n.t(:is_invalid)) unless sentinel.valid?
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
require_dependency 'rate_limiter'
|
require_dependency 'rate_limiter'
|
||||||
require_dependency 'system_message'
|
require_dependency 'system_message'
|
||||||
|
require_dependency 'trashable'
|
||||||
|
|
||||||
class PostAction < ActiveRecord::Base
|
class PostAction < ActiveRecord::Base
|
||||||
class AlreadyActed < StandardError; end
|
class AlreadyActed < StandardError; end
|
||||||
|
|
||||||
include RateLimiter::OnCreateRecord
|
include RateLimiter::OnCreateRecord
|
||||||
|
include Trashable
|
||||||
|
|
||||||
attr_accessible :post_action_type_id, :post_id, :user_id, :post, :user, :post_action_type, :message, :related_post_id
|
attr_accessible :post_action_type_id, :post_id, :user_id, :post, :user, :post_action_type, :message, :related_post_id
|
||||||
|
|
||||||
|
@ -12,8 +14,6 @@ class PostAction < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :post_action_type
|
belongs_to :post_action_type
|
||||||
|
|
||||||
acts_as_paranoid
|
|
||||||
|
|
||||||
rate_limit :post_action_rate_limiter
|
rate_limit :post_action_rate_limiter
|
||||||
|
|
||||||
validate :message_quality
|
validate :message_quality
|
||||||
|
@ -114,8 +114,7 @@ class PostAction < ActiveRecord::Base
|
||||||
|
|
||||||
def self.remove_act(user, post, post_action_type_id)
|
def self.remove_act(user, post, post_action_type_id)
|
||||||
if action = where(post_id: post.id, user_id: user.id, post_action_type_id: post_action_type_id).first
|
if action = where(post_id: post.id, user_id: user.id, post_action_type_id: post_action_type_id).first
|
||||||
action.destroy
|
action.trash!
|
||||||
action.deleted_at = Time.zone.now
|
|
||||||
action.run_callbacks(:save)
|
action.run_callbacks(:save)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,10 +4,12 @@ require_dependency 'topic_view'
|
||||||
require_dependency 'rate_limiter'
|
require_dependency 'rate_limiter'
|
||||||
require_dependency 'text_sentinel'
|
require_dependency 'text_sentinel'
|
||||||
require_dependency 'text_cleaner'
|
require_dependency 'text_cleaner'
|
||||||
|
require_dependency 'trashable'
|
||||||
|
|
||||||
class Topic < ActiveRecord::Base
|
class Topic < ActiveRecord::Base
|
||||||
include ActionView::Helpers
|
include ActionView::Helpers
|
||||||
include RateLimiter::OnCreateRecord
|
include RateLimiter::OnCreateRecord
|
||||||
|
include Trashable
|
||||||
|
|
||||||
def self.max_sort_order
|
def self.max_sort_order
|
||||||
2**31 - 1
|
2**31 - 1
|
||||||
|
@ -18,9 +20,17 @@ class Topic < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
versioned if: :new_version_required?
|
versioned if: :new_version_required?
|
||||||
acts_as_paranoid
|
|
||||||
after_recover :update_flagged_posts_count
|
|
||||||
after_destroy :update_flagged_posts_count
|
def trash!
|
||||||
|
super
|
||||||
|
update_flagged_posts_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def recover!
|
||||||
|
super
|
||||||
|
update_flagged_posts_count
|
||||||
|
end
|
||||||
|
|
||||||
rate_limit :default_rate_limiter
|
rate_limit :default_rate_limiter
|
||||||
rate_limit :limit_topics_per_day
|
rate_limit :limit_topics_per_day
|
||||||
|
|
|
@ -442,11 +442,11 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
posts.order("post_number desc").each do |p|
|
posts.order("post_number desc").each do |p|
|
||||||
if p.post_number == 1
|
if p.post_number == 1
|
||||||
p.topic.destroy
|
p.topic.trash!
|
||||||
# TODO: But the post is not destroyed. Why?
|
# TODO: But the post is not destroyed. Why?
|
||||||
else
|
else
|
||||||
# TODO: This should be using the PostDestroyer!
|
# TODO: This should be using the PostDestroyer!
|
||||||
p.destroy
|
p.trash!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,6 @@ The following Ruby Gems are used in Discourse:
|
||||||
* [rack-mini-profiler](https://rubygems.org/gems/rack-mini-profiler)
|
* [rack-mini-profiler](https://rubygems.org/gems/rack-mini-profiler)
|
||||||
* [sass](https://rubygems.org/gems/sass)
|
* [sass](https://rubygems.org/gems/sass)
|
||||||
* [rest-client](https://rubygems.org/gems/rest-client)
|
* [rest-client](https://rubygems.org/gems/rest-client)
|
||||||
* [rails3_acts_as_paranoid](https://rubygems.org/gems/rails3_acts_as_paranoid)
|
|
||||||
* [activerecord-postgres-hstore](https://rubygems.org/gems/activerecord-postgres-hstore)
|
* [activerecord-postgres-hstore](https://rubygems.org/gems/activerecord-postgres-hstore)
|
||||||
* [fastimage](https://rubygems.org/gems/fastimage)
|
* [fastimage](https://rubygems.org/gems/fastimage)
|
||||||
* [seed-fu](https://rubygems.org/gems/seed-fu)
|
* [seed-fu](https://rubygems.org/gems/seed-fu)
|
||||||
|
|
|
@ -37,8 +37,7 @@ class PostDestroyer
|
||||||
# Feature users in the topic
|
# Feature users in the topic
|
||||||
Jobs.enqueue(:feature_topic_users, topic_id: @post.topic_id, except_post_id: @post.id)
|
Jobs.enqueue(:feature_topic_users, topic_id: @post.topic_id, except_post_id: @post.id)
|
||||||
|
|
||||||
# Actually soft-delete the post :)
|
@post.trash!
|
||||||
@post.destroy
|
|
||||||
|
|
||||||
Topic.reset_highest(@post.topic_id)
|
Topic.reset_highest(@post.topic_id)
|
||||||
@post.update_flagged_posts_count
|
@post.update_flagged_posts_count
|
||||||
|
|
32
lib/trashable.rb
Normal file
32
lib/trashable.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
module Trashable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
default_scope where(with_deleted_scope_sql)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def with_deleted
|
||||||
|
# lifted from acts_as_paranoid, works around http://stackoverflow.com/questions/8734669/rails-3-1-3-unscoped-scope
|
||||||
|
scope = self.scoped.with_default_scope
|
||||||
|
scope.where_values.delete(with_deleted_scope_sql)
|
||||||
|
scope
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_deleted_scope_sql
|
||||||
|
self.scoped.table[:deleted_at].eq(nil).to_sql
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def trash!
|
||||||
|
self.update_column(:deleted_at, DateTime.now)
|
||||||
|
end
|
||||||
|
|
||||||
|
def recover!
|
||||||
|
# see: https://github.com/rails/rails/issues/8436
|
||||||
|
self.class.unscoped.update_all({deleted_at: nil}, id: self.id)
|
||||||
|
raw_write_attribute :deleted_at, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -222,14 +222,14 @@ describe Guardian do
|
||||||
it 'correctly handles post visibility' do
|
it 'correctly handles post visibility' do
|
||||||
Guardian.new(user).can_see?(post).should be_true
|
Guardian.new(user).can_see?(post).should be_true
|
||||||
|
|
||||||
post.destroy
|
post.trash!
|
||||||
post.reload
|
post.reload
|
||||||
Guardian.new(user).can_see?(post).should be_false
|
Guardian.new(user).can_see?(post).should be_false
|
||||||
Guardian.new(admin).can_see?(post).should be_true
|
Guardian.new(admin).can_see?(post).should be_true
|
||||||
|
|
||||||
post.recover
|
post.recover!
|
||||||
post.reload
|
post.reload
|
||||||
topic.destroy
|
topic.trash!
|
||||||
topic.reload
|
topic.reload
|
||||||
Guardian.new(user).can_see?(post).should be_false
|
Guardian.new(user).can_see?(post).should be_false
|
||||||
Guardian.new(admin).can_see?(post).should be_true
|
Guardian.new(admin).can_see?(post).should be_true
|
||||||
|
|
|
@ -196,7 +196,7 @@ describe TopicView do
|
||||||
|
|
||||||
describe "filter_posts_after" do
|
describe "filter_posts_after" do
|
||||||
it "returns undeleted posts after a post" do
|
it "returns undeleted posts after a post" do
|
||||||
topic_view.filter_posts_after(p1.post_number).should == [p2, p3, p5]
|
topic_view.filter_posts_after(p1.post_number).map(&:id).should == [p2.id, p3.id, p5.id]
|
||||||
topic_view.should_not be_initial_load
|
topic_view.should_not be_initial_load
|
||||||
topic_view.index_offset.should == 1
|
topic_view.index_offset.should == 1
|
||||||
topic_view.index_reverse.should be_false
|
topic_view.index_reverse.should be_false
|
||||||
|
|
|
@ -29,7 +29,7 @@ describe InvitesController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "destroys the invite" do
|
it "destroys the invite" do
|
||||||
Invite.any_instance.expects(:destroy)
|
Invite.any_instance.expects(:trash!)
|
||||||
delete :destroy, email: invite.email
|
delete :destroy, email: invite.email
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ describe PostActionsController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "works with a deleted post" do
|
it "works with a deleted post" do
|
||||||
flagged_post.destroy
|
flagged_post.trash!
|
||||||
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam]
|
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam]
|
||||||
response.should be_success
|
response.should be_success
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe PostsController do
|
||||||
context "deleted post" do
|
context "deleted post" do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
post.destroy
|
post.trash!
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can't find deleted posts as an anonymous user" do
|
it "can't find deleted posts as an anonymous user" do
|
||||||
|
@ -121,7 +121,7 @@ describe PostsController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls recover" do
|
it "calls recover" do
|
||||||
Post.any_instance.expects(:recover)
|
Post.any_instance.expects(:recover!)
|
||||||
xhr :put, :recover, post_id: post.id
|
xhr :put, :recover, post_id: post.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ describe PostAction do
|
||||||
|
|
||||||
it "should reset counts when a topic is deleted" do
|
it "should reset counts when a topic is deleted" do
|
||||||
PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
|
PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
|
||||||
post.topic.destroy
|
post.topic.trash!
|
||||||
PostAction.flagged_posts_count.should == 0
|
PostAction.flagged_posts_count.should == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ describe Post do
|
||||||
let(:post) { Fabricate(:post, post_args) }
|
let(:post) { Fabricate(:post, post_args) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
post.destroy
|
post.trash!
|
||||||
post.reload
|
post.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ describe Post do
|
||||||
|
|
||||||
describe "recovery" do
|
describe "recovery" do
|
||||||
before do
|
before do
|
||||||
post.recover
|
post.recover!
|
||||||
post.reload
|
post.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ describe UserAction do
|
||||||
|
|
||||||
other_stats.should == expecting
|
other_stats.should == expecting
|
||||||
|
|
||||||
public_topic.destroy
|
public_topic.trash!
|
||||||
stats_for_user.should == []
|
stats_for_user.should == []
|
||||||
stream_count.should == 0
|
stream_count.should == 0
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ describe UserAction do
|
||||||
|
|
||||||
category = Fabricate(:category, secure: true)
|
category = Fabricate(:category, secure: true)
|
||||||
|
|
||||||
public_topic.recover
|
public_topic.recover!
|
||||||
public_topic.category = category
|
public_topic.category = category
|
||||||
public_topic.save
|
public_topic.save
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user