【问题标题】:Rails: validates_length_of导轨:validates_length_of
【发布时间】:2023-04-07 21:34:01
【问题描述】:

我想在我的销售模型中验证销售折扣。

用于创建销售的表单接收来自我的仓库模型的产品数据并将其保存在销售记录中:

<%= f.select(:product, Warehouse.pluck(:product).uniq, {prompt:true}, {class: 'form-control'}) %>

Warehouse 模型具有为相应产品指定的折扣。现在我想检查sale.product 是否等于warehouse.product,然后设置此销售的折扣限制。那可能吗?像这样的:

validates_length_of :discount, maximum: Warehouse.where(:product => @sales.product).pluck(:discount), message: "Discount is to high"

提前非常感谢!

【问题讨论】:

  • 你看过 Rails 文档吗?它似乎正是您所需要的:validates :name, length: { maximum: 2 }guides.rubyonrails.org/active_record_validations.html#length
  • 是的。但我不想给出修复编号,因为编号取决于要销售的具体产品。
  • 你在运行时需要这个,不确定,但我认为你可以将 lambda 传递给 maximum
  • 等等。您要限制字符串的长度还是数值
  • 那你不想验证length,而是验证numericality

标签: ruby-on-rails


【解决方案1】:

首先,您应该验证 numericality 的数值。

自定义验证是不必要的。您不必使用常量或文字或其他类评估时间值!使用procsThey will be called!

您将键作为比较传递,然后将 proc 作为值传递,因此在验证期间会调用它。

valudates_numericality_of :discount,
  less_than_or_equal_to: proc { |model| Something.query(whatever).pluck(:wow) },
  message: "is too high"

注意:您可能还应该添加检查是否为阳性。


奖励(纯属好玩,最好不要使用):几乎相同的代码带有大量箭头
(按顺序:符号&lt;=,hashrocket =&gt;,stabby-lambda -&gt; () {}):

valudates_numericality_of :discount,
  :<= => -> (model) { Something.query(whatever).pluck(:wow) },
  :message => "is too high"

请注意,1.9 哈希语法不适用于 &lt;=(如 &lt;=: value)这样的符号,因此您必须坚持使用哈希火箭,这是……另一种纯粹的乐趣。

【讨论】:

    【解决方案2】:

    您可以尝试使用自定义验证

    在你的模型中

    validate :maximum_discout
    
      def maximum_discount
        if Warehouse.where(:product => @sales.product).pluck(:discount).all?{|d| d > self.discount }
          errors.add(:discount, "It should not cross the maximum discount")
        end
      end
    

    【讨论】:

      【解决方案3】:

      对于此任务,您应该使用自定义验证。请看:http://guides.rubyonrails.org/active_record_validations.html#custom-methods

      【讨论】:

        【解决方案4】:

        要添加到D-side 的答案(并使用this reference),您还需要处理相关数据(不调用新的数据库查询):

        #app/models/sale.rb
        class Sale < ActiveRecord::Base
            belongs_to :product, class_name: "Warehouse", foreign_key: "product", inverse_of: :sales
            validates :discount, numericality: { less_than_or_equal_to: Proc.new{|sale| sale.product.discount } } 
        
        end
        
        #app/models/warehouse.rb
        class Warehouse < ActiveRecord::Base
             has_many :sales, inverse_of: :product
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多