我是Ruby on Rails的初学者,这是由某人开发的ruby on rails。
有两种类型的用户:注册用户"用户"角色和注册用户" admin"作用。
如果用户的角色="用户",则会发生太多重定向,但如果用户是" admin"则不会发生此重定向。我还没弄明白为什么。
首先,如果用户是管理员,我会在日志中得到这个:
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语句;我希望简化这一点,但这是一个不同的问题和另一个学习机会。
如果用户是普通用户,则&#34;重定向&#34;将在用户成为普通用户后立即发生
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都会触发重定向......但首先,我想找到为什么它会对具有角色用户的用户产生影响与角色管理员。我稍后会担心优化。任何帮助将不胜感激。
这是config / 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
接下来是controllers / 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
这是models / 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
最后,我找到了这个models / 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
添加了controllers / 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 :(得分:1)
问题似乎在这里:
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
由于某种原因,当您不是管理员时,会引发该异常,并且当您重定向到ProductsController#home
我没有看到您的产品控制器代码,但问题应该存在。让我知道。
答案 1 :(得分:0)
由于我无法发表评论或赞成Paulo的答案,因此我将此处留给所有遇到类似问题的人。
他的回答让我在我的控制器中更好地了解导致无限重定向,特别是触发的动作并最终解决了这个问题。
我也在使用devise/cancancan
。
具体来说,我有companies_controller.rb
。
此外,在before_action中我有类似下面的内容
before_action :set_company, only: :show
并且set_company操作是这个
def set_company
...
authorize! params[:action].to_sym, @company || Company
end
我一删除授权!调用重定向循环停止。 我还没有想到是什么导致了循环,因为我的用户角色似乎很好,但这绝对是原因。