Я сделал некоторые предположения, потому что не весь пример кода имел для меня смысл, но основная схема была бы:
- Использовать обратные вызовы ActiveRecord вместо проверки ввода в контроллере
- Убедитесь, что отношения установлены правильно, чтобы вы могли строить объекты из них
- Используйте
first_or_create
для очистки родительского поиска / создания
В моем опыте манипулируя вводомparams - это кодовый запах.Иногда вам приходится это делать, но обычно это говорит о том, что что-то неправильно спроектировано.
Некоторые из манипуляций с параметрами, которые вы можете выполнить с помощью обратных вызовов ActiveRecord .Одно замечание, похоже, что located_at_text
не является частью модели, вам нужно проверить это в контроллере или добавить attr_reader
к модели (но я не думаю, что вам следует, это еще один запах кода).
class Location < ApplicationRecord
validates :name, presence: true
end
Установите отношения в модели.Это позволит вам создавать связанные записи.
class Location < ApplicationRecord
belongs_to :located_at
validates :name, presence: true
end
class LocatedAt < ApplicationRecord
has_many :locations
end
Обычно эта установка будет содержать идентификатор для LocatedAt
в URL (например, .../#{located_at_id}/location/new
), но это не требуется, если высобираюсь явно передать идентификатор local_at, который выглядит так, как вы.
Это выходит за рамки вашего вопроса, но если вы отказываетесь от шаблона URL, где родительские идентификаторы передаются в URL,для ваших пользователей было бы очень полезно предоставить им какой-либо тип автозаполнения поиска или элемент пользовательского интерфейса, который позволит им явно знать, что они создают новую запись LocatedAt
.Это также облегчит вашу жизнь, потому что вы можете передать идентификатор, полученный в результате поиска, или параметр триггера, чтобы сначала создать новую запись.
Наконец, используйте first_or_create
, чтобы проверить, что located_at
существует (и если не создать).Предполагается, что в LocationAt есть только одно поле, и оно называется name
.
Примечание. Я изменил модель с Location, так как для меня не имело смысла, что Location будет искать себя впример.
@located_at = LocatedAt
.where(name: params[:form_name][:located_at_text])
.first_or_create
@location = @located_at.locations.new(location_params)