访问控制器 before_action 中的资源的 "rails way" 是什么
What's the "rails way" to access a resource in a controller's before_action
我正在使用 Pundit 来授权我控制器中的操作。我的第一次尝试是在 after_action 钩子中授权模型:
class CompaniesController < InheritedResources::Base
after_action :authorize_company, except: :index
def authorize_company
authorize @company
end
这让我可以使用定义 @company
的默认控制器操作,这样我就不会访问数据库两次。但是,这对破坏性操作不利,因为它不会在 之后授权操作我已经搞砸了数据库。
所以,我改为使用 before_action
挂钩:
class CompaniesController < InheritedResources::Base
before_action :authorize_company, except: :index
def authorize_company
@company = Company.find(params.require(:id))
authorize @company
end
现在,我不允许未经授权的人删除资源等...但我正在访问数据库两次。有没有访问 @company
而不访问数据库两次的方法?
事实证明 rails 控制器有一个 resource
如果模型存在并且 build_resource
用于像 new
.
这样的操作
class CompaniesController < InheritedResources::Base
before_action :authorize_company, except: :index
private
def authorize_company
authorize resource
rescue ActiveRecord::RecordNotFound
authorize build_resource
end
end
既然你要求 "rails way" 这就是你在没有 InheritedResources
的 "plain old rails" 中设置它的方式。
class CompaniesController < ApplicationController
before_action :authorize_company, except: [:new, :index]
def new
@company = authorize(Company.new)
end
def index
@companies = policy_scope(Company)
end
# ...
private
def authorize_company
@company = authorize(Company.find(params[:id]))
end
end
如果您真的想要使用回调,您可以这样做:
class CompaniesController < ApplicationController
before_action :authorize_company, except: [:new, :index]
before_action :authorize_companies, only: [:index]
before_action :build_company, only: [:new]
# ...
private
def authorize_company
@company = authorize(Company.find(params[:id]))
end
def authorize_companies
@companies = policy_scope(Company)
end
def build_companies
@company = authorize(Company.new)
end
end
是的,您可以使用三个代码分支编写一个回调方法,但这具有较低的循环复杂度,并且每个方法只完成一项工作。
我正在使用 Pundit 来授权我控制器中的操作。我的第一次尝试是在 after_action 钩子中授权模型:
class CompaniesController < InheritedResources::Base
after_action :authorize_company, except: :index
def authorize_company
authorize @company
end
这让我可以使用定义 @company
的默认控制器操作,这样我就不会访问数据库两次。但是,这对破坏性操作不利,因为它不会在 之后授权操作我已经搞砸了数据库。
所以,我改为使用 before_action
挂钩:
class CompaniesController < InheritedResources::Base
before_action :authorize_company, except: :index
def authorize_company
@company = Company.find(params.require(:id))
authorize @company
end
现在,我不允许未经授权的人删除资源等...但我正在访问数据库两次。有没有访问 @company
而不访问数据库两次的方法?
事实证明 rails 控制器有一个 resource
如果模型存在并且 build_resource
用于像 new
.
class CompaniesController < InheritedResources::Base
before_action :authorize_company, except: :index
private
def authorize_company
authorize resource
rescue ActiveRecord::RecordNotFound
authorize build_resource
end
end
既然你要求 "rails way" 这就是你在没有 InheritedResources
的 "plain old rails" 中设置它的方式。
class CompaniesController < ApplicationController
before_action :authorize_company, except: [:new, :index]
def new
@company = authorize(Company.new)
end
def index
@companies = policy_scope(Company)
end
# ...
private
def authorize_company
@company = authorize(Company.find(params[:id]))
end
end
如果您真的想要使用回调,您可以这样做:
class CompaniesController < ApplicationController
before_action :authorize_company, except: [:new, :index]
before_action :authorize_companies, only: [:index]
before_action :build_company, only: [:new]
# ...
private
def authorize_company
@company = authorize(Company.find(params[:id]))
end
def authorize_companies
@companies = policy_scope(Company)
end
def build_companies
@company = authorize(Company.new)
end
end
是的,您可以使用三个代码分支编写一个回调方法,但这具有较低的循环复杂度,并且每个方法只完成一项工作。