<commit_before>class RelatedContent < ActiveRecord::Base
  RELATED_CONTENT_SCORE_THRESHOLD = Setting['related_content_score_threshold'].to_f
  RELATIONABLE_MODELS = %w{proposals debates}.freeze

  belongs_to :parent_relationable, polymorphic: true, touch: true
  belongs_to :child_relationable, polymorphic: true, touch: true
  has_one :opposite_related_content, class_name: 'RelatedContent', foreign_key: :related_content_id
  has_many :related_content_scores

  validates :parent_relationable_id, presence: true
  validates :parent_relationable_type, presence: true
  validates :child_relationable_id, presence: true
  validates :child_relationable_type, presence: true
  validates :parent_relationable_id, uniqueness: { scope: [:parent_relationable_type, :child_relationable_id, :child_relationable_type] }

  after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? }

  scope :not_hidden, -> { where('positive_score - negative_score / LEAST(nullif(positive_score + negative_score, 0), 1) >= ?', RELATED_CONTENT_SCORE_THRESHOLD) }

  def score(value)
    RelatedContentsScore.create(user_id: current_user, related_content_id: self, score: value)
    RelatedContentsScore.create(user_id: current_user, related_content_id: opposite_related_content, score: value)
  end

  private

  def create_opposite_related_content
    related_content = RelatedContent.create!(opposite_related_content: self, parent_relationable: child_relationable, child_relationable: parent_relationable)
    self.opposite_related_content = related_content
  end
end<commit_msg>Add act as paranoid to related content, with not_hidden scope using hidden_at<commit_after>class RelatedContent < ActiveRecord::Base
  RELATED_CONTENT_SCORE_THRESHOLD = Setting['related_content_score_threshold'].to_f
  RELATIONABLE_MODELS = %w{proposals debates}.freeze

  acts_as_paranoid column: :hidden_at
  include ActsAsParanoidAliases

  belongs_to :parent_relationable, polymorphic: true, touch: true
  belongs_to :child_relationable, polymorphic: true, touch: true
  has_one :opposite_related_content, class_name: 'RelatedContent', foreign_key: :related_content_id
  has_many :related_content_scores

  validates :parent_relationable_id, presence: true
  validates :parent_relationable_type, presence: true
  validates :child_relationable_id, presence: true
  validates :child_relationable_type, presence: true
  validates :parent_relationable_id, uniqueness: { scope: [:parent_relationable_type, :child_relationable_id, :child_relationable_type] }

  after_create :create_opposite_related_content, unless: proc { opposite_related_content.present? }

  scope :not_hidden, -> { where('positive_score - negative_score / LEAST(nullif(positive_score + negative_score, 0), 1) >= ?', RELATED_CONTENT_SCORE_THRESHOLD) }
  scope :not_hidden, -> { where(hidden_at: nil) }

  def score(value)
    RelatedContentsScore.create(user_id: current_user, related_content_id: self, score: value)
    RelatedContentsScore.create(user_id: current_user, related_content_id: opposite_related_content, score: value)
  end

  private

  def create_opposite_related_content
    related_content = RelatedContent.create!(opposite_related_content: self, parent_relationable: child_relationable, child_relationable: parent_relationable)
    self.opposite_related_content = related_content
  end
end
{'fraction_non_alphanumeric': 0.07539329177797566, 'fraction_numerical': 0.0011872959335114278, 'mean_word_length': 7.641025641025641, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5804888', 'n_tokens_mistral': 1057, 'n_tokens_neox': 1008, 'n_words': 207}