我有一个处理航班的Ruby on Rails(Ruby 2.5.1,Rails 5.1)应用程序;除此之外,它还有Flight
模型和Airline
模型,Flight belongs_to :airline
和Airline has_many :flights
。 Airline
有一个iata_code
列,其中包含双字母IATA航空公司代码(即AA
,UA
,WN
,F9
)。< / 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' %>
然后,在我的航班控制器的create
和update
操作中,我尝试在保存航班之前查找航空公司,并设置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模型的验证,并相应地返回表单验证错误?
答案 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