В Rails, где я могу разместить логику обнаружения ошибок для проверки ввода пользователя из формы? - PullRequest
0 голосов
/ 02 марта 2019

Я пишу приложение с минимальными рельсами, чтобы узнать немного больше о рельсах.

Приложение будет отслеживать вещи (книги для начала).Поэтому мне нужно «Место», чтобы определить, где находится данный элемент.

create_table "locations", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
  t.bigint "located_at"
  t.integer "sort"
  t.string "name"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["name"], name: "index_locations_on_name", unique: true
end

"sort" не имеет значения для этого вопроса.

В форме для создания нового местоположения пользователь получаетввести имя (скажем, «X») и при желании сказать, где находится само «X» (скажем, «Y»).

Поэтому для создания местоположения в контроллере я сделаю что-то вроде

@location = Location.new(location_params)

Но мне нужно превратить «Y» в location.id для «Y».Кроме того, если «Y» не существует, мне нужно вызвать какую-то ошибку.

Теперь у меня есть виртуальная переменная located_at_text, и в контроллере я делаю это:

modified_location_params = location_params
located_at_text = modified_location_params["located_at_text"]
located = nil
located = Location.find_by_name(located_at_text) unless located_at_text.nil? or located_at_text.strip.empty?
modified_location_params["located_at"] = located.nil? ? 0 : located.id

@location = Location.new(modified_location_params)

(я не знаю, почему я не могу возиться с location_params ... но это был бы другой вопрос ... я буду беспокоиться об этом, как только узнаю, куда лучше всего поставитьмой код. Также мое приложение не возражает против 0 для location.id).

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

Что такое "путь рельсов"?

1 Ответ

0 голосов
/ 02 марта 2019

Я сделал некоторые предположения, потому что не весь пример кода имел для меня смысл, но основная схема была бы:

  1. Использовать обратные вызовы ActiveRecord вместо проверки ввода в контроллере
  2. Убедитесь, что отношения установлены правильно, чтобы вы могли строить объекты из них
  3. Используйте 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...