Rails 3 — действие индекса не загружается по умолчанию на контроллере

#ruby-on-rails-3 #routes

#ruby-on-rails-3 #маршруты

Вопрос:

Теперь у меня выполняется новая rails 3 установка rvm 1.9.2 , я сгенерировал контроллер, используя следующую инструкцию:

 rails generate controller blog index
  

Результат таков

       create  app/controllers/blog_controller.rb
      route  get "blog/index"
      invoke  erb
      create    app/views/blog
      create    app/views/blog/index.html.erb
      invoke  test_unit
      create    test/functional/blog_controller_test.rb
      invoke  helper
      create    app/helpers/blog_helper.rb
      invoke    test_unit
      create      test/unit/helpers/blog_helper_test.rb
  

но в браузере, когда я пытаюсь добраться до http://localhost:3000/blog , я получаю:

 No route matches "/blog"
  

но если я наберу http://localhost:3000/blog/index

он отображает представление индекса.

разве это не работает как Rails 2? где я получаю представление индекса по умолчанию, просто указав имя контроллера в URL?

Спасибо.

Ответ №1:

Если вы заглянете в routes.rb , вы увидите

 get "/blog/index" => "blog#index"
  

Так что просто удалите его с помощью

 get "/blog" => "blog#index"
  

или вы можете использовать resources здесь.

Но только вопрос: почему вы используете единственную форму? Бессмысленно обращаться к index к singular noun. Вы должны использовать или «blog #show» в качестве ресурса или «blogs #index» в качестве ресурсов.

Соглашения в Rails — это своего рода подвал. Не нарушайте их, если можете следовать им

Ответ №2:

Для rails 3:

 match '/blog', :controller => 'blog', :action => 'index'
  

Комментарии:

1. Это выглядело бы лучше так: match '/blog' => 'blog#index' вы так не думаете?

Ответ №3:

Rails generate по умолчанию не генерирует ресурсы для вашего контроллера. Вы указали одно действие для вашего контроллера, ‘index’, поэтому в вашем случае вы получите это в config / routes.rb:

 Blog::Application.routes.draw do
    get "blog/index"
  

Проще всего было бы изменить это на:

   get "blog", :to => 'blog#index'
  

ян.

Ответ №4:

Это предположение, основанное на моем опыте работы с Rails 2, но вот что, я думаю, происходит:

Если бы вы сгенерировали свой контроллер с scaffold опцией (это все еще в Rails 3, верно?), это создало бы модель в дополнение к вашему контроллеру и добавило соответствующие маршруты через вызов map.resources (или эквивалент Rails 3) — это последний бит, который дает вам /models маршруты, которые вы ожидаете.

Но поскольку вы только что сгенерировали контроллер, модель не была создана, и, следовательно, Rails не вставляет map.resources инструкцию в routes.rb — map.resources действительно имеет смысл только тогда, когда есть модель, лежащая в основе вашего контроллера. На самом деле, я не думаю, что это добавляет какие-либо специальные маршруты при создании контроллера; вы получаете доступ к своему индексу одним из маршрутов по умолчанию: /:controller/:action .

Итак, если вы хотите получить доступ к своему индексу из /blog , вам придется добавить маршрут самостоятельно. К счастью, оно должно быть однострочным.

Надеюсь, это поможет!

PS: И если вы параноик, вы захотите отключить эти маршруты по умолчанию перед запуском в производство — они позволяют запросам GET запускать действия, которые изменяют вашу базу данных (например, GET:/blog/destroy ), открывая вас для атак с подделкой межсайтовых запросов.

Ответ №5:

Добавьте это в свой файл routes.rb match ':controller(/:action(/:id))(.:format)'
Будет лучше, если вы добавите его в нижней части файла routes.rb.
Проблема с этим подходом заключается в том, что он сделает все ваши действия доступными через запрос get. Так что будьте осторожны с этим.

Ответ №6:

Вместо ручной маршрутизации вы можете перейти к /app/controllers/application_controller.rb и добавить пустой метод индексации

 def index
end
  

убедитесь, что ваш сгенерированный контроллер расширяет контроллер приложения, и boom все ваши сгенерированные контроллеры будут делать то, что вы хотите
Протестировано на Rails 3.2.*