【问题标题】:Validation issues with HTML tagsHTML 标签的验证问题
【发布时间】:2021-10-09 16:28:16
【问题描述】:

数据库保存输入表单中的 HTML 标记,我想剥离它们以进行正确的验证。我在 IRB 中测试了以下方法,它似乎工作正常。但是我不知道如何使用此方法进行验证。

这是我模型中的代码:

class Task < ActiveRecord::Base
  validates strip_tag(:text), length: {minimum: 3}, uniqueness: true
  
  def strip_tag(record)
    record.split(/\<.*?\>/).map(&:strip).reject(&:empty?).join(' ').gsub(/\s,/,',')
  end
end

我面临的问题是正在检查唯一性和长度是否大于 3,但是由于 HTML 标记,例如很容易创建重复项。

删除标签后重复的示例:

"<p><span style=\"color: #1d3d70; font-family: -apple-system, system-ui, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: #ffffff;\">Testing 8449</span></p>" 

还有这个:

"<p>Testing 8449</p>" 

删除 HTML 标记后两者应该具有相同的值,例如,我想防止这种重复。

【问题讨论】:

  • 为什么不用ActionView::Helpers::SanitizeHelper#strip_tags 而不是重新发明轮子?
  • strip_tags 是要走的路。但是,您必须在该字段中存储 HTML 标记是否有商业原因?以这种方式验证独特性可能会在未来造成痛苦和折磨。另一种方法是将strip_tags 的结果存储在另一个字段中,然后在该字段上执行验证。
  • 我将改用trip_tag。 @ryan 我正在存储标签,因为用户想要丰富的格式文本。他们可以更改字体、创建表格、插入超链接、使用段落等......就像他们在 Word 中所做的一样

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-5


【解决方案1】:

我认为您需要另一列,例如条纹标签文本的check_sum 并验证该列的唯一性,因此在before_validation 回调中您剥离标签,然后计算并设置条纹标签文本的check_sum

# migration add new column check_sum
t.string   :checksum,     null: false

# model
class Task < ActiveRecord::Base
  attr_accessor :striped_text

  before_validation :check_sum_pure_text

  validates :striped_text, length: {minimum: 3}
  validates_uniqueness_of :checksum
  
  def strip_tag(record)
   # ... 
  end

  def check_sum_pure_text
   self.striped_text = strip_tag(rich_text)
   # NOTE about case_sensitive
   # 'user' == 'User' ???
   self.checksum = Digest::MD5.hexdigest(self.striped_text)
  end
end

注意:您需要多一列checksum 的原因是关于性能,预先计算checksum 列将有助于加快检查唯一性验证。

【讨论】:

    【解决方案2】:

    我最终将 html 标记剥离为值。我从我想检查的列的数据库中获得了一个集合,以查看它是否是唯一的并从那里剥离 html 标签。我使用该值来查看数据库中的集合是否包含该值。我不知道如何在数据库查询期间去除标签。

    class Task < ActiveRecord::Base
      
      validate :check_duplicates
    
      private
    
      def check_duplicates
        strip_txt = ActionController::Base.helpers.strip_tags(text)
        errors.add(
          :text, 
          'Text already stored. Text must be unique'
        ) if (
           Task.select('text')
           .pluck(:text)
           .collect{|e|ActionController::Base.helpers.strip_tags(e)}.include? strip_txt)
       end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 2015-08-06
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 2022-08-03
      • 2013-04-13
      相关资源
      最近更新 更多