Проверка поля формы Rails, которое должно пройти через другую модель перед сохранением - PullRequest
0 голосов
/ 28 мая 2018

У меня есть приложение 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).

Для формы входа в рейс Iхотите, чтобы пользователь мог вводить произвольный код IATA, а не выбирать авиакомпанию из выпадающего списка.Если введенный пользователем код IATA совпадает с записью в таблице Airline, то в столбце Flight.airline_id должен быть указан идентификатор этой авиакомпании.Если код IATA не совпадает с авиакомпанией в моей базе данных, то авиакомпанию следует создать с использованием предоставленного кода IATA, и этому новому идентификатору авиакомпании следует присвоить 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) нет, вместо этого airline_iata в форме полета недопустимо.

Как я могу настроить его так, чтобы это поле формы, которое должно взаимодействовать с моделью аэропорта перед отправкой, могло запустить проверку модели аэропорта на рейсполе формы и, соответственно, вернуть ошибки проверки формы?

1 Ответ

0 голосов
/ 28 мая 2018

Вы можете попробовать использовать вложенные атрибуты формы и добавить хук before_validation, который переопределит ассоциацию:

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

В flight.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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...