简体   繁体   中英

How to control respond_to based on variable in Rails controller?

The dilemma

I'm using a before_filter in my controller that restricts access to admins. However, I want to allow access public access to some methods based on request format . See the index method to understand what I'm talking about.

application_controller.rb

class ApplicationController < ActionController::Base

  # ...

  def current_user
    @current_user ||= User.find_by_id(session[:user])
  end

  def superuser_required
    redirect_to login_path unless current_user.superuser?
  end


end

items_controller.rb

class ItemsController < ApplicationController

  before_filter :superuser_required
  layout 'superuser'

  def index
    @items = Item.all
    respond_to do |format|
      format.html
      format.js # I want public to have access to this
    end
  end

  def show
    @item = Item.find(params[:id])
    respond_to do |format|
      format.html
    end
  end

  def new
    @item = Item.new
    respond_to do |format|
      format.html
    end
  end

  # remaining controller methods
  # ...

end

Filters have access to the request object which has a format method you can use to obtain the request format. Change your before filter so that if the format is JavaScript then the request processing is allowed to proceed. Something like:

def superuser_required
  return true if request.format == Mime::JS
  redirect_to login_path unless current_user.superuser?
end

Way easier than I expected

2 days later

class FoosController < ActiveRecord::Base

  # use :except to open `show` action for public js access
  before_filter :superuser_required, :except => 'index'

  # before_filter does not apply here
  def index
    @foos = Foo.all

    respond_to do |format|

      # restrict behavior on html access for superusers
      format.html do
        superuser_required  # functions same as before_filter
      end

      # unrestricted on js access for public but only shows foo.id and foo.name
      format.js do
        render :text => @foo.to_json(:only => [:id, :name])
      end

    end
  end

  # restricted to superuser per before_filter
  def new
    @foo = Foo.new
    respond_to do |format|
      format.html
    end
  end

  # restricted to superuser per before_filter
  def show
    @foo = Foo.find(params[:id])
    respond_to do |format|
      format.html
    end
  end

end

Either I totally missed something when I was learning about respond_to or my original question was completely incoherent. I just read it again, though, and it still seems like this only (and most) appropriate way to address my issue.

Surprisingly, I couldn't really find any examples of this kind of behavior on the web either. Oh well. Now I know more about respond_to , right?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM