Маршрутизация Rails в XML/JSON без взбесившихся представлений

У меня загадочная проблема. В очень простом приложении Ruby у меня есть три класса: Drivers, Jobs и Vehicles. Все три класса состоят только из идентификатора и имени. Все три класса имеют одинаковые методы #index и #show и отображают только в JSON или XML (на самом деле это верно для всех их CRUD-методов, они идентичны во всем, кроме названия). Просмотров нет. Например:

def index
  @drivers= Driver.all
  respond_to do |format|
    format.js  { render :json => @drivers}
    format.xml  { render :xml => @drivers}
  end
end

def show
  @driver = Driver.find(params[:id])
  respond_to do |format|
    format.js  { render :json => @driver}
    format.xml  { render :xml => @driver}
  end
end

Модели также минималистичны и содержат только:

class Driver< ActiveRecord::Base
  validates_presence_of :name
end

В route.rb у меня есть:

map.resources :drivers
map.resources :jobs
map.resources :vehicles

map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'

Я могу выполнять POST/create, GET/index и PUT/update для всех трех классов, а GET/read также работал, пока я не установил плагин ActiveRecord «имеет много полиморфов» и не добавил в environment.rb:

require File.join(File.dirname(__FILE__), 'boot')
require 'has_many_polymorphs' 
require 'active_support'

Теперь для двух из трех классов я больше не могу читать. Если я перехожу к localhost:3000/drivers, все они хорошо отображаются в XML, но если я перехожу к localhost:3000/drivers/3, я получаю сообщение об ошибке:

Processing DriversController#show (for 127.0.0.1 at 2009-06-11 20:34:03) [GET]
  Parameters: {"id"=>"3"}
  [4;36;1mDriver Load (0.0ms)[0m   
  [0;1mSELECT * FROM "drivers" WHERE ("drivers"."id" = 3) [0m

ActionView::MissingTemplate 
  (Missing template drivers/show.erb in view path app/views):
  app/controllers/drivers_controller.rb:14:in `show'

  ...etc

За этим следует еще одна неожиданная ошибка:

Processing ApplicationController#show (for 127.0.0.1 at 2009-06-11 21:35:52)[GET]
  Parameters: {"id"=>"3"}
NameError (uninitialized constant ApplicationController::AreaAccessDenied):

...etc

Что здесь происходит? Почему один и тот же код работает для одного класса, но не работает для двух других? Почему он пытается сделать #view в ApplicationController?

Я обнаружил, что если я создам простое представление HTML для каждого из трех классов, они будут работать нормально. К каждому классу я добавляю:

format.html # show.html.erb

При этом переход на localhost:3000/drivers/3 отображает элемент в HTML, и я не получаю никаких ошибок в журнале. Но если прикрепить .xml к URL-адресу, для двух классов снова произойдет сбой (с тем же сообщением об ошибке, что и раньше), а один выведет XML, как и ожидалось. Еще более странно, что в двух неудачных классах при добавлении .js к URL-адресу (для запуска рендеринга JSON) вместо этого я получаю вывод HTML!

Возможно ли, что это как-то связано с плагином «имеет много полиморфов»? Я слышал, что у людей возникают проблемы с маршрутизацией после его установки. Удаление «имеет много полиморфов» и «активная поддержка» из environment.rb (и перезагрузка сервера), похоже, не имеет никакого значения. Но у меня проблемы начались после его установки. Я потратил несколько часов на эту проблему и начинаю немного отчаиваться, Google практически не выдает никакой информации, что заставляет меня подозревать, что я, должно быть, пропустил что-то элементарное. Любое просветление или подсказка с благодарностью!

JS


person John Schulze    schedule 11.06.2009    source источник
comment
Возможно, мне следует добавить некоторые подробности о моей настройке: rails (2.3.2) activerecord (2.3.2, 2.2.2) activeresource (2.3.2, 2.2.2) has_many_polymorphs (2.13) mongrel (1.1.5) mysql (2.7. 3)   -  person John Schulze    schedule 12.06.2009


Ответы (3)


Если вы установили много полиморфов в качестве плагина, вы должны удалить его из вендора/плагинов, а не из environment.rb. Не могли бы вы rm -rf этот плагин и попробуйте еще раз.

person Ryan Oberoi    schedule 11.06.2009
comment
Спасибо за ваш ответ. Я удалил плагин has many polymorphs, но, к сожалению, без изменений. - person John Schulze; 12.06.2009
comment
Абсолютно, всегда делайте это, чтобы быть уверенным. - person John Schulze; 12.06.2009
comment
Ok. Вот что может происходить. До того, как вы пошли по этому пути, возможно, вы использовали другую версию rails/active_support. Я не уверен, что вы изменили, но вы больше не используете цикл response_to в своем коде, как ожидалось. Найдите в Google, почему answer_to не работает должным образом. Эта ссылка может быть полезна при отладке вашей ситуации: neeraj.name/blog/articles/ - person Ryan Oberoi; 12.06.2009
comment
Да, это звучит как отличная возможность. Спасибо за ссылку. Пару дней назад у меня была проблема с версиями Rails 2.2.2 и 2.3.2, и я был немного разочарован (на первый взгляд) плохим управлением версиями в RoR. Я ожидаю получить сообщение об ошибке, говорящее о неправильной версии или требующей версии. n.n.n, но нет, вместо этого я получил неопределенный метод: CreateConnection в ActiveRecord. - person John Schulze; 12.06.2009

Ok. Я сдался. Вернулся к предыдущей версии «имеет много полиморфов» и применил свои изменения одно за другим, запуская тесты после каждого, чтобы убедиться, что оно все еще работает. Примерно час спустя, и я думаю, что все /app/ вещи такие же, как и тогда, когда я столкнулся с проблемой. «имеет много полиморфов» переустанавливается и требуется вместе с «активной поддержкой», а классы/модели/представления верны (т.е. без рендеринга HTML и без представлений). И угадайте, что; все работает отлично! Я не знаю, должно ли это меня радовать или огорчать - в любом случае, я все еще очень хотел бы знать, что здесь пошло не так...

JS

P.S. О, и если я собираюсь продолжить работу с RoR, мне придется сделать SVN приоритетом. Это абсолютно необходимо даже для такого крошечного проекта, поскольку кажется, что RoR ломается очень легко и загадочно (это не первые 5+ часов WTF, которые у меня были).

person John Schulze    schedule 11.06.2009
comment
У меня был такой опыт. Не только в рельсах. Может быть, вы можете сделать разницу между двумя вещами, чтобы действительно прибить это. Ну, я думаю, мое предложение было действительно лучшим ответом. Извините :) - person Ryan Oberoi; 12.06.2009
comment
Если программа больше 10-15 строк, вам следует использовать систему контроля версий. :) Но я бы предложил git, он намного мощнее. В любом случае используйте систему управления версиями и вносите небольшие изменения отдельных функций; это значительно облегчает отслеживание. Если бы вы сделали это с git, вы могли бы использовать git bisect, чтобы отследить, когда он сломался. (если это не экологическая проблема) - person DGM; 30.12.2011
comment
О, я, и я был в течение нескольких лет. Однако до сих пор не подружился с git, так что пока это старый добрый SVN. Возможно, однажды... - person John Schulze; 29.01.2012

В настоящее время лучше всего перезапустить приложение с нуля. рельсы хороши, как это.

person Ryan Oberoi    schedule 11.06.2009
comment
Знаете что, именно к этому я и прибегал. Вероятно, потребуется намного меньше времени, чтобы повторно применить мои изменения одно за другим и протестировать после каждого, чтобы попытаться понять это. Позор, правда, мне начал нравиться RoR... - person John Schulze; 12.06.2009
comment
Может быть, вы можете сделать разницу между двумя вещами, чтобы действительно прибить это. Или лучше - просто заархивируйте и пришлите мне. Мне очень любопытно, как ранняя версия попала в шланг. В этом смысле Rails хрупок, и у Rails 2.3.* определенно есть свои особенности. Я хотел бы быть более полезным, но, как вы, несомненно, пришли бы к выводу, эта ситуация была почти безвыходной издалека. :) Рад, что у вас все получилось. Перезапуск с нуля в некоторых ситуациях с рельсами происходит намного быстрее, особенно с совершенно новыми проектами, такими как ваш. - person Ryan Oberoi; 12.06.2009
comment
Ага. Сейчас работает с SVN, так что в будущем диагностика такого рода вещей должна быть проще. И вы правы, у меня не было особой надежды на то, что кто-то сможет помочь. Спасибо за ваш вклад! - person John Schulze; 12.06.2009