Лучшие практики для обработки маршрутов для подклассов STI в rails

Мои представления и контроллеры Rails завалены redirect_to , link_to , и form_for вызовов методов. Иногда link_to и redirect_to явно указаны в путях, которые они связывают (например, link_to 'New Person', new_person_path ), но часто пути являются неявными (например, link_to 'Show', person ).

Я добавляю наследование одной таблицы (STI) в свою модель (скажем, Employee ), и все эти методы нарушают работу экземпляра подкласса (скажем, Employee ); когда rails выполняет link_to @person , возникает ошибка undefined method employee_path 'для # : 0x0000010226d038> . Rails ищет маршрут, определяемый именем класса объекта, которым является сотрудник. Эти маршруты сотрудников не определены, и нет контроллера сотрудников, поэтому действия также не определены.

Этот вопрос задавался раньше:

  1. На StackOverflow ответ - редактировать каждый экземпляр link_to и т. д. во всей кодовой базе и явно укажите путь
  2. В StackOverflow снова два человека предлагают использовать маршруты . rb для сопоставления ресурсов подкласса с родительским классом ( map.resources: employee,: controller => 'people' ). Главный ответ в том же вопросе SO предполагает приведение типов к каждому объекту экземпляра в базе кода с использованием .becomes
  3. Еще один в StackOverflow , главный ответ - в лагере Do Repeat Yourself , и предлагает создать повторяющиеся строительные леса для каждого подкласса.
  4. Вот тот же вопрос, снова в SO, где верхний ответ кажется просто неправильным (Rails magic Just Works!)
  5. В другом месте в Интернете я нашел это сообщение в блоге , где F2Andy рекомендует редактировать путь везде в коде.
  6. В сообщении в блоге Наследование одной таблицы и маршруты RESTful в Logical Reality Design, рекомендуется сопоставить ресурсы подкласса контроллеру суперкласса, как в ответе SO 2 выше.
  7. У Алекса Рейснера есть сообщение Single Table Inheritance in Rails , в котором он выступает против сопоставления ресурсы дочерних классов к родительскому классу в routes.rb , так как он перехватывает сбои маршрутизации только из link_to и redirect_to , но не из form_for . Поэтому он рекомендует вместо этого добавить метод к родительскому классу, чтобы подклассы лгали о своем классе. Звучит хорошо, но его метод дал мне ошибку undefined локальная переменная или метод `child 'для # .

Итак, ответ, который кажется наиболее элегантным и наиболее согласованным (но это еще не все этот элегантный, ни , большой консенсус), не добавление ресурсов в ваш routes.rb . За исключением того, что это не работает для form_for . Мне нужна ясность! Чтобы исключить вышеперечисленные варианты, я могу

  1. сопоставить ресурсы подкласса с контроллером суперкласса в routes.rb (и надеюсь, мне не нужно вызывать form_for для каких-либо подклассов)
  2. Переопределение рельсов внутренних методов, чтобы классы лежали друг напротив друга
  3. Измените каждый экземпляр в коде, где путь к действию объекта вызывается неявно или явно, либо изменяя путь, либо приводя тип объекта.

Со всеми этими противоречивыми ответами мне нужно решение. Мне кажется, хорошего ответа нет. Это недостаток конструкции рельсов? Если да, то можно ли исправить эту ошибку? А если нет, то я Я надеюсь, что кто-то сможет меня прямо объяснить, расскажет о плюсах и минусах каждого варианта (или объяснит, почему это не вариант), и какой из них правильный и почему. Или есть правильный ответ, которого я не нахожу в Интернете?

169
задан Community 23 May 2017 в 12:02
поделиться