Rails - 从控制器添加验证错误

时间:2015-04-29 09:43:31

标签: ruby-on-rails validation

预订模型belongs_to DiscountCode。预订表格有一个折扣码的字符串输入,转到控制器中的DiscountCode:

updated_params = booking_params
if updated_params[:discount_code]
  updated_params[:discount_code] = DiscountCode.find_by code: updated_params[:discount_code]
end
@booking = Booking.new(updated_params)

所以现在如果输入的代码不存在,updated_pa​​rams [:discount_code]为零,这与没有输入折扣代码的情况相同。我宁愿在if语句的@ booking.discount_code中添加一个错误,但我在控制器中,这可能吗?

1 个答案:

答案 0 :(得分:3)

这类事情的解决方案通常是在控制器中使用@booking做一些非常简单,标准,不可知和脚手架的事情,比如@booking = Booking.new(params[:booking])@booking.update_attributes(params[:booking])。始终尽量使控制器方法尽可能标准化,并将逻辑推入模型和数据中。

因此,这导致我们通过Booking setter方法传递折扣代码。如果我们已经没有来自Rails的setter方法,那么我们需要添加它。我们假设在预订中已经存在类似“has_one:discount_code”的关联。我们可以编写一个setter方法来从代码中进行这种关联,并像这样验证它。

(请注意,在名为“DiscountCode”的类中有一个名为“code”的字段会让人感到困惑 - 您将要编写@discount_code.code,这就是问题“是''代码'是一串字母和'12dafj1213'这样的数字,或者是从数据库中加载的ActiveRecord对象的'代码'?“。我建议将类重命名为”Discount“(所以你会说@ discount.code)或重命名”代码“字段到”令牌“(所以你会说@ discount_code.token)。我没有在我的解决方案中解决这个问题,我坚持你的命名,所以我的代码看起来很混乱所有”code_code“的东西

class Booking
  attr_accessor :discount_code_code
  has_one :discount_code

  before_validation :set_discount_code_from_discount_code_code
  validate :check_we_have_discount_code_if_we_have_discount_code_code

  def set_discount_code_from_discount_code_code
    unless self.discount_code_code.blank?
      self.discount_code = DiscountCode.find_by_code(self.discount_code_code)
    end
  end

  def check_we_have_discount_code_if_we_have_discount_code_code
    if !self.discount_code_code.blank? && !self.discount_code
      self.errors.add(:discount_code, "is not a valid discount code")
    end    
  end
end

你的表格(我希望是一个form_for @booking)应该包含这样的内容

<%= f.text_field :discount_code_code %>

将通过诸如

之类的参数来实现
params = {:booking => {:discount_code_code => "12dafj1213"}}

然后在控制器中你应该说

@booking = Booking.new(params[:booking])
if @booking.save
  ...etc