Rails:validates_length_of

时间:2015-12-16 10:52:40

标签: ruby-on-rails

我想验证我的销售模式中的促销折扣。

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

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

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

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

非常感谢提前!

4 个答案:

答案 0 :(得分:5)

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

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

您将密钥作为比较传递,然后将 proc 作为值传递,以便在验证期间调用它。

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

注意:您可能还应该检查一下是否为正。

奖金(纯粹的乐趣,最好不要使用):几乎相同的代码,带有壮观的箭头数量
(按顺序:符号<=,hashrocket =>,stabby-lambda -> () {}):

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

请注意,1.9哈希语法不适用于像<=这样的符号(如<=: value),所以你必须坚持使用这个符号,这是......另一点纯粹乐趣。

答案 1 :(得分:0)

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

在您的模型中

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

要添加到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