Methods for limiting the Rails render format to html

后端 未结 5 2015
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 11:18

I have a Rails 2.1.2 site that only has html templates e.g. jobs.html.erb, so when I request a restful resource:

www.mysite.com/jobs/1

相关标签:
5条回答
  • 2020-12-09 11:48

    I was getting non-sensical requests for image format on HTML files, triggerring a 500 with MissingTemplate. I edicted the following at the end of my action:

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

    And now instead of getting error reports, we emit a 406 to that mischievious requester.

    0 讨论(0)
  • 2020-12-09 11:57

    You can use Rails Per-Action Overwrite feature. What's this? --> It’s also possible to override standard resource handling by passing in a block to respond_with specifying which formats to override for that action:

    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
    

    :except And :only Options

    You can also pass in :except and :only options to only support formats for specific actions (as you do with before_filter):

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

    The :any Format

    If you’re still want to use respond_to within your individual actions, use the :any resource format that can be used as a wildcard match against any unspecified formats:

    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
    
    0 讨论(0)
  • 2020-12-09 12:00

    Ben's solution works.

    Consider the responds_to solution, though. It's cleaner since it allows flexibility when you will inevitably need to open up an action for a JavaScript json or xml call. Then you won't have to add

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

    I personally like the respond_to block; it's very descriptive.

    respond_to do |wants|
      wants.html
     end
    

    Any format not specified in the block will automatically cause a HTTP 406 Not Acceptable to be returned. That's nice.

    0 讨论(0)
  • 2020-12-09 12:13

    If you don't want to use responds_to, you can do this:

    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
    

    That will run before all requests and only let those that do not specify format at all, or that specify html format through. All others get 404'd. You can create a public/406.html if you want to return 406 not acceptable.

    0 讨论(0)
  • 2020-12-09 12:13

    In your routes you can simply remove the line:

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

    And the ".xyz" will no longer be routed, resulting in 404 errors/.

    0 讨论(0)
提交回复
热议问题