预订模型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_params [:discount_code]为零,这与没有输入折扣代码的情况相同。我宁愿在if语句的@ booking.discount_code中添加一个错误,但我在控制器中,这可能吗?
答案 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