2009-11-04 2 views
12

У меня есть сайт Rails 2.1.2, который имеет только html-шаблоны, например. jobs.html.erb, поэтому, когда я прошу успокоительной ресурс:Методы ограничения формата рендеринга Rails на html

www.mysite.com/jobs/1

Это делает мою работу в HTML, однако, если я прошу:

www.mysite.com/jobs/1.xml

Я получаю ошибку:

Template is missing Missing template jobs/show.xml.erb in view path c:/workspace/mysite/app/views

что еще хуже то, что я могу просить что-то вроде

www.mysite.com/jobs/1.xyz

И действительно я вижу ошибку:

Template is missing Missing template jobs/show.xyz.erb in view path c:/workspace/mysite/app/views

Для stricly присутствует только HTML содержание, то, что является чистым и простым способом сказать Rails, что я не хочу, чтобы сделать что-либо, кроме .html.erb файлов.

Важно отметить, что:

  • Некоторые из моих действий контроллера содержат условные вызовы метода визуализации() в то время как другие используют поведение Rails по умолчанию, т.е. если вы не вызываете визуализации(), то Будет показан шаблон с именем youraction.html.erb.
  • Мой код не использует метод responds_to()

Было бы здорово, если бы решение не было на уровне визуализации/responds_to, как я бы изменить значительное количество действий. Возможно, есть способ настроить Rails так, чтобы отображались только html-шаблоны?

ответ

7

Если вы не хотите использовать responds_to, вы можете сделать это:

class ApplicationController < ActionController::Base 
    before_filter :allow_only_html_requests 

    ... 

    def allow_only_html_requests 
    if params[:format] && params[:format] != "html" 
     render :file => "#{RAILS_ROOT}/public/404.html" 
    end 
    end 

    ... 

end 

Это будет работать, прежде чем все запросы и пусть только те, которые не определяет формат вообще, или указать формат HTML через , Все остальные получают 404'd. Вы можете создать public/406.html, если вы хотите вернуть 406 неприемлемым.

+1

Это фактически не возвращает 404, но он просто отображает '404.html' как ответ 200. Вам нужно будет добавить ': status => 404' (или': status =>: not_found'). Аналогично, для 406 вы хотите использовать ': status => 406' (или': status =>: not_acceptable'). – Peeja

+1

Это также не удается, если запрос использует заголовок «accept» для запроса типа ответа, поскольку он не сохраняется в параметрах – zimkies

14

В маршрутах вы можете просто удалить строку:

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

и «.xyz» больше не будет направляться, в результате ошибок 404 /.

+0

Удаление этой строки не решает проблему в Rails 3.2.6: она уже закомментирована, но ошибка с отсутствием шаблона все еще появляется. – collimarco

5

Решение Бен работает.

Рассмотрите решение responses_to. Он более чист, так как он обеспечивает гибкость, когда вам неизбежно придется открыть действие для вызова JavaScript json или xml. Тогда вам не нужно будет добавлять

skip_before_filter :allow_only_html_requests, :only => [:show] 

Мне лично нравится блок response_to; это очень описательно.

respond_to do |wants| 
    wants.html 
end 

Любой формат не указан в блоке будет автоматически вызвать HTTP 406 не приемлемо, чтобы быть возвращены. Это мило.

+1

Согласовано. Блок responses_to открывает мир гибкости, и если вы можете потратить время на добавление одного для .html к каждому из ваших действий с контроллером, это гораздо более перспективное решение. – Ben

10

Вы можете использовать Rails Переопределить. Что это? -> Также можно переопределить стандартную обработку ресурсов путем передачи в блоке с respond_with уточнения, какие форматы переопределить для этого действия:

class UsersController < ApplicationController::Base 

    respond_to :html, :xml, :json 

    # Override html format since we want to redirect to a different page, 
    # not just serve back the new resource 
    def create 
    @user = User.create(params[:user]) 
    respond_with(@user) do |format| 
     format.html { redirect_to users_path } 
    end 
    end 
end 

: кроме А: только параметры

Вы также можете передать в: кроме и: только варианты для только форматы поддержки для конкретных действий (как вы делаете с before_filter):

class UsersController < ApplicationController::Base 
    respond_to :html, :only => :index 
    respond_to :xml, :json, :except => :show 
    ... 
end 

в: любой формат

Если вы все еще хотите использовать respond_to в пределах ваших индивидуальных действий, использовать: любой формат ресурс, который может быть использован в качестве подстановочного матча против любых неопределенных форматов:

class UsersController < ApplicationController::Base 

    def index 

    @users = User.all 

    respond_to do |format| 
     format.html 
     format.any(:xml, :json) { render request.format.to_sym => @users } 
    end 
    end 
end 
+1

Это только Rails 3. – Jared

+0

Джаред, не могли бы вы уточнить, какой из трех вариантов - только Rails 3! Я запускаю Rails 2.3.4, и: работает любой параметр. – leviathan

1

я получал не бы бессмысленно запросы на формат изображения в файлах HTML, триггер 500 с MissingTemplate. Я edicted следующего в конце моих действий:

def show 
    # [...] 
    respond_to :html 
end 

И теперь вместо того, чтобы получать сообщения об ошибках, мы испускаем 406 к этому mischievious запрашивающему.

Смежные вопросы