refactor Topic validation

introduce a couple of custom validators
fix minor discrepancies in tests
copy I18n error message keys to default location
clean up validation invocation
move some responsibilities out of validator into class
This commit is contained in:
Matt Van Horn
2013-05-22 21:52:12 -07:00
parent 872995db57
commit 806255b3c4
21 changed files with 178 additions and 56 deletions

View File

@@ -36,15 +36,24 @@ class Topic < ActiveRecord::Base
rate_limit :limit_topics_per_day
rate_limit :limit_private_messages_per_day
validate :title_quality
validates_presence_of :title
validate :title, -> { SiteSetting.topic_title_length.include? :length }
before_validation :sanitize_title
validates :title, :presence => true,
:length => { :in => SiteSetting.topic_title_length,
:allow_blank => true },
:quality_title => { :unless => :private_message? },
:unique_among => { :unless => Proc.new { |t| (SiteSetting.allow_duplicate_topic_titles? || t.private_message?) },
:message => :has_already_been_used,
:allow_blank => true,
:case_sensitive => false,
:collection => Proc.new{ Topic.listable_topics } }
after_validation do
self.title = TextCleaner.clean_title(TextSentinel.title_sentinel(title).text) if errors[:title].empty?
end
serialize :meta_data, ActiveRecord::Coders::Hstore
before_validation :sanitize_title
validate :unique_title
belongs_to :category
has_many :posts
has_many :topic_allowed_users
@@ -142,22 +151,6 @@ class Topic < ActiveRecord::Base
RateLimiter.new(user, "pms-per-day:#{Date.today.to_s}", SiteSetting.max_private_messages_per_day, 1.day.to_i)
end
# Validate unique titles if a site setting is set
def unique_title
return if SiteSetting.allow_duplicate_topic_titles?
# Let presence validation catch it if it's blank
return if title.blank?
# Private messages can be called whatever they want
return if private_message?
finder = Topic.listable_topics.where("lower(title) = ?", title.downcase)
finder = finder.where("id != ?", self.id) if self.id.present?
errors.add(:title, I18n.t(:has_already_been_used)) if finder.exists?
end
def fancy_title
return title unless SiteSetting.title_fancy_entities?
@@ -168,19 +161,6 @@ class Topic < ActiveRecord::Base
Redcarpet::Render::SmartyPants.render(title)
end
def title_quality
# We don't care about quality on private messages
return if private_message?
sentinel = TextSentinel.title_sentinel(title)
if sentinel.valid?
# clean up the title
self.title = TextCleaner.clean_title(sentinel.text)
else
errors.add(:title, I18n.t(:is_invalid))
end
end
def sanitize_title
if self.title.present?
self.title = sanitize(title, tags: [], attributes: [])