在保存

时间:2018-05-28 00:09:55

标签: ruby-on-rails

我有一个处理航班的Ruby on Rails(Ruby 2.5.1,Rails 5.1)应用程序;除此之外,它还有Flight模型和Airline模型,Flight belongs_to :airlineAirline has_many :flightsAirline有一个iata_code列,其中包含双字母IATA航空公司代码(即AAUAWNF9)。< / p>

对于航班登记表,我希望用户能够输入任意IATA代码,而不是从下拉列表中选择航空公司。如果用户输入的IATA代码与Airline表中的记录匹配,则Flight.airline_id列应设置为该航空公司的ID。如果IATA代码 与我的数据库中的航空公司不匹配,则应使用提供的IATA代码创建航空公司,并且应将新航空公司的ID分配给Flight.airline_id

我目前通过在我的添加/编辑航班表单中添加航空公司IATA代码字段来工作(请注意,表单字段的名称为:airline_iata而不是:airline_id):

<%= f.label :airline_iata, "Airline code" %>
<%= f.text_field :airline_iata, class: "form-control code airline-iata", maxlength: 2, placeholder: 'AA' %>

然后,在我的航班控制器的createupdate操作中,我尝试在保存航班之前查找航空公司,并设置airline_id参数(create在下面,但update类似):

def create
  params[:flight][:airline_id] = Airline.find_or_create_by!(:iata_code => params[:flight][:airline_iata].upcase).id
  @flight = current_traveler.flights.build(flight_params)

  if @flight.save
    redirect_to event_path(current_traveler.event)
  else
    render "new"
  end

end

这种方法对我有用,除了,我无法弄清楚如何从航班表格对航空公司IATA代码字段进行验证。航空公司模型验证代码(presence: true, length: { is: 2 }, uniqueness: { case_sensitive: false }),因此如果用户输入无效的IATA代码,航空公司创建将失败,因此航班创建将失败。但是,我不会在Flight表单上得到通常的验证错误(例如错误消息,突出显示错误的表单字段),因为Flight的问题是airline_id(不直接在Flight表单上)是' t present,而不是Flight表单中的airline_iata无效。

如何设置它以便在提交之前必须与机场模型交互的此表单字段可以在Flight表单字段上运行Airport模型的验证,并相应地返回表单验证错误?

1 个答案:

答案 0 :(得分:1)

您可以尝试使用嵌套表单属性并添加将覆盖关联的before_validation挂钩:

<%= f.fields_for :airline do |airline_form| %>
  <%= airline_form.label :iata_code, "Airline code" %>
  <%= airline_form.text_field :iata_code %>
<% end %>

在飞行中.rb你应该

accept_nested_attributes_for :airline
before_validation :check_existing_airline, on: :create

def check_existing_airline
  if airline.new_record? && existing_airline = Airline.find_by(iata_code: airline.iata_code)
    self.airline = exisitng_airline
  end
end