<commit_before># Product Associating 表示产品之间的关联。常见的关联包括销售包装、产品换代等。
# source 是来源产品。如组合后的产品、被换代的产品、不兼容产品中的主产品。
# target 是目标产品。如参与组合的产品、替换其它产品的新产品、不兼容产品中的次要产品。
# product_association_code 是产品关联：
#   CPLM 是产品补充   complement
#   ICPT 是产品不兼容 incompatibility
#   OBSL 是产品废弃   obsolescence
#   PCKG 是销售包装   package
#   SBST 是产品替代   substitute

class Unidom::Product::ProductAssociating < ActiveRecord::Base

  self.table_name = 'unidom_product_associatings'

  include Unidom::Common::Concerns::ModelExtension

  validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0    }

  belongs_to :source, class_name: 'Unidom::Product::Product'
  belongs_to :target, class_name: 'Unidom::Product::Product'

  scope :source_is, ->(product) { where source_id: to_id(product) }
  scope :target_is, ->(product) { where target_id: to_id(product) }

  def self.associate!(source, with: target, due_to: 'PCKG', ordinal: 1, quantity: 1, at: Time.now)

    associating = source_is(source).target_is(with).product_association_coded_as(due_to).valid_at.alive.first
    associating.soft_destroy if associating.present?

    #if associating.present?<commit_msg>1, Improve the Product Associating model for Rails 5.<commit_after># Product Associating 表示产品之间的关联。常见的关联包括销售包装、产品换代等。
# source 是来源产品。如组合后的产品、被换代的产品、不兼容产品中的主产品。
# target 是目标产品。如参与组合的产品、替换其它产品的新产品、不兼容产品中的次要产品。
# product_association_code 是产品关联：
#   CPLM 是产品补充   complement
#   ICPT 是产品不兼容 incompatibility
#   OBSL 是产品废弃   obsolescence
#   PCKG 是销售包装   package
#   SBST 是产品替代   substitute

class Unidom::Product::ProductAssociating < Unidom::Product::ApplicationRecord

  self.table_name = 'unidom_product_associatings'

  include Unidom::Common::Concerns::ModelExtension

  validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0    }

  belongs_to :source, class_name: 'Unidom::Product::Product'
  belongs_to :target, class_name: 'Unidom::Product::Product'

  scope :source_is, ->(product) { where source_id: to_id(product) }
  scope :target_is, ->(product) { where target_id: to_id(product) }

  def self.associate!(source, with: target, due_to: 'PCKG', ordinal: 1, quantity: 1, at: Time.now)

    associating = source_is(source).target_is(with).product_association_coded_as(due_to).valid_at.alive.first
    associating.soft_destroy if associating.present?

    #if associating.present?
{'fraction_non_alphanumeric': 0.1065989847715736, 'fraction_numerical': 0.00338409475465313, 'mean_word_length': 5.955882352941177, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '818355', 'n_tokens_mistral': 1004, 'n_tokens_neox': 1062, 'n_words': 163}