2016-07-23 11 views
-1

私はRuby on Railsの初心者です。これは誰かが開発したRuby on Railsです。Ruby on Rails ERR_TOO_MANY_REDIRECTS指定されたユーザロールのエラー

「ユーザー」ロールを持つ登録ユーザーと「管理」ロールを持つ登録ユーザーの2種類のユーザーがあります。

リダイレクトが多すぎるのは、ユーザーのロール=「ユーザー」の場合のみですが、ユーザーが「管理者」の場合はそうなりません。なぜ私はまだ理解していない。

まず、ユーザが管理者であれば、私はログにこれを取得します:

Started GET "/" for ::1 at 2016-07-22 18:18:17 -0700 
Processing by ProductsController#home as HTML 
    ^[[1m^[[35mUser Load (0.1ms)^[[0m SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 11]] 
controller_path: products 
resource: product 
method: product_params 
after the parms setting => ${params} 
Debugging in the Ability.rb... 
User: #<User:0x007fe6d7f0f670> 
user is admin 
    ^[[1m^[[36mProduct Load (0.3ms)^[[0m ^[[1mSELECT "products".* FROM "products"^[[0m 
    ^[[1m^[[35mVersion Load (1.1ms)^[[0m SELECT "versions".* FROM "versions" 
    ^[[1m^[[36mReltype Load (1.0ms)^[[0m ^[[1mSELECT "reltypes".* FROM "reltypes"^[[0m 

と、より多くのSQL文。私はそれを単純化するのが大好きですが、それは別の質問と別の学習機会です。

ユーザーが正規のユーザーである場合、ユーザーが通常のユーザー

Started GET "/" for ::1 at 2016-07-22 18:25:23 -0700 
Processing by ProductsController#home as HTML 
    ^[[1m^[[36mUser Load (0.1ms)^[[0m ^[[1mSELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1^[[0m [["id", 11]] 
controller_path: products 
resource: product 
method: product_params 
after the parms setting => ${params} 
Debugging in the Ability.rb... 
User: #<User:0x007fe6d13dca88> 
user is regular user 
Redirected to http://localhost:3000/ 
Completed 302 Found in 6ms (ActiveRecord: 0.1ms) 


Started GET "/" for ::1 at 2016-07-22 18:25:23 -0700 
Processing by ProductsController#home as HTML 
    ^[[1m^[[35mUser Load (0.1ms)^[[0m SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 11]] 
controller_path: products 
resource: product 
method: product_params 
...repeat... for many more 

した後、「リダイレクト」は右どうなる私の推測では、ランディングページは、このページで使用するすべてのデータをプルしようとしていることですそれぞれのSQLはリダイレクトをトリガーします...しかし、まず、ロールのユーザーとロールの管理者の違いは何ですか?後で最適化について心配します。どんな助けでも大歓迎です。ここで

はここ/ routes.rbを

Rails.application.routes.draw do 
    resources :groupings 
    resources :platforms 
    resources :versions 
    resources :reltypes 
    resources :products 

    # Devise stuff 
    devise_for :users 
    devise_scope :user do 
    get '/login' => 'devise/sessions#new' 
    get '/logout' => 'devise/sessions#destroy' 
    end 

    resources :users, :controller => "users" 
    unauthenticated :user do 
    resources :products, only: [:index, :show] 
    resources :versions, only: [:index, :show] 
    resources :reltypes, only: [:index, :show] 
    resources :platforms, only: [:index, :show] 
    resources :groupings, only: [:index, :show] 
    end 

    # You can have the root of your site routed with "root" 
    root to: 'products#home' 

    namespace :api, :defaults => {:format => :json} do 
    resources :platforms 
    resources :versions 
    resources :reltypes 
    resources :products 
    resources :groupings 
    end 
end 

次に、コントローラ/ application.rb

class ApplicationController < ActionController::Base 
    # include DeviseTokenAuth::Concerns::SetUserByToken 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 

    # Devise: redirect to login page if user not logged in 
    before_action :authenticate_user! 

    before_filter do 
    resource = controller_path.singularize.to_sym 
    method = "#{resource}_params" 
    Rails.logger.debug("controller_path: #{controller_path}") 
    Rails.logger.debug("resource: #{resource}") 
    Rails.logger.debug("method: #{method}") 

    params[resource] &&= send(method) if respond_to?(method, true) 
    end 

    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])} 
    end 

    # CanCan: if user authorization fails, catch and modify 
    check_authorization :unless => :devise_controller? 

    rescue_from CanCan::AccessDenied do |exception| 
    redirect_to root_url, :alert => exception.message 
    end 
end 

設定は、モデル/ user.rb

最後に
class User < ActiveRecord::Base 
    devise :database_authenticatable, :registerable, 
    :recoverable, :rememberable, :trackable, :validatable 

    before_save :default_values 

    def default_values 
    # self.role ||= 'user' 
    self.role = "user" 
    end 

    def is?(requested_role) 
    self.role == requested_role 
    end 
end 

です私はこのモデル/ activity.rbを見つけました(私はいくつかのデバッグステートメントをここに入れようとしました:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    # Define abilities for the passed in user here. For example: 
    # 
    user ||= User.new # guest user (not logged in) 
    Rails.logger.debug("Debugging in the Ability.rb...") 
    Rails.logger.debug("User: #{user}") 

    if user.is? "admin" 
     Rails.logger.debug("user is admin") 
     can :manage, :all 
    else 
     Rails.logger.debug("user is regular user") 
     can :read, :all 
    end 
    end 
end 

コントローラ/ products_controller.rbが追加されました(Sri Vishnu Totakuraの提案通り)。ちょっとしたスペースを節約するために、コードを更新/破棄するのをスキップしました。

class ProductsController < ApplicationController 
    load_and_authorize_resource #for CanCan 

    before_action :set_product, only: [:show, :edit, :update, :destroy] 

    # GET /products 
    # GET /products.json 
    def index 
    @products = Product.all 
    end 

    def home 
    @products = Product.all 
    @versions = Version.all 
    @platforms = Platform.all 
    @reltypes = Reltype.all 
    @prevrels = Prevrel.all 
    end 

    # GET /products/1 
    # GET /products/1.json 
    def show 
    end 

    # GET /products/new 
    def new 
    # puts "params for new: " 
    # puts params 
    @product = Product.new 
    end 

    # GET /products/1/edit 
    def edit 
    end 

    # POST /products 
    # POST /products.json 
    def create 
    puts "params for create: " 
    puts params 
    @product = Product.new(product_params) 

    respond_to do |format| 
     if @product.save 
     format.html { redirect_to @product, notice: 'Product was successfully created.' } 
     format.json { render :show, status: :created, location: @product } 
     else 
     format.html { render :new } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    def update 
    ... 
    end 

    def destroy 
    ... 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_product 
     @product = Product.find(params[:id]) 
     @versions = @product.versions 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def product_params 
     params.require(:product).permit(:name) 
    end 
end 
+0

'ProductsController#home'アクションでこれを引き起こすコードがあるかもしれません。 'ProductsController'からのコードを貼り付けることができた場合に役立ちます – aBadAssCowboy

答えて

1

問題がここにあるようだ。

rescue_from CanCan::AccessDenied do |exception| 
    redirect_to root_url, :alert => exception.message 
end 

何らかの理由であなたが管理者いないとき、その例外が発生し、そしてあなたがProductsController#homeにリダイレクトするようあなたは、ループに陥りますこれはroot to: 'products#home'

あなたの製品のコントローラコードは表示されませんが、そこに問題があるはずです。お知らせ下さい。

+0

投稿/追加されました。ありがとう! –

0

Pauloさんの回答はコメントできません。私はこれと同じ問題を抱えているすべての人にこのまま残しておきます。

私のコントローラでは、無限のリダイレクト、特にトリガされたアクションを引き起こして、最終的にこの問題を解決してくれました。

私はdevise/cancancanも使用していました。

特に、私はcompanies_controller.rbを持っていました。

はさらに、before_actionに私は、次の

before_action :set_company, only: :show 

のようなものを持っていたとset_companyアクションは、できるだけ早く私は、AUTHORIZEを削除して、この

def set_company 
    ... 
    authorize! params[:action].to_sym, @company || Company 
end 

でした!リダイレクトループが停止したことを呼び出します。 私のユーザの役割はうまくできていると思われたので、ループの原因はわかりませんでしたが、これは間違いなく原因でした。

関連する問題