狂欢自定义创建用户会话操作
spree customizing the create user sessions action
我使用 STI 向我的 Spree::User 模型 class 添加了继承。我有一个 :type 列,它可以是 (Spree::Guest, Spree::Writer, or Spree::Reader)。
在管理员端的身份验证中,我只想验证作者和 reader。解决此问题的最佳选择是什么?
我试图将创建操作重写为:
def create
authenticate_spree_user!
if spree_user_signed_in? && (spree_current_user.role?(:writer) || spree_current_user.role?(:reader))
respond_to do |format|
format.html {
flash[:success] = Spree.t(:logged_in_succesfully)
redirect_back_or_default(after_sign_in_path_for(spree_current_user))
}
format.js {
user = resource.record
render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
}
end
else
flash.now[:error] = t('devise.failure.invalid')
render :new
end
end
在这种情况下,当尝试使用 :guest 类型的用户进行身份验证时,它会重定向到带有无效失败消息的新操作 (ok),但用户会以某种方式通过身份验证 (nok)。
我认为这不是解决问题的好方法,控制器应该只是一个控制器。我宁愿走那条路:
Spree 使用 cancancan (or cancan in older branches) for authorization and that's how Spree implements that。我不知道你为什么想要那个 STI 解决方案 - 我只是为此创建新的自定义 Spree::Role
但正如我所说我不知道你为什么选择 STI 方式 - 这应该也能正常工作。
无论如何,您可以为该能力文件添加一个装饰器,并额外检查 user.is_a? Spree::Guest
等,或者通过 register_ability
注册新能力 - 例如 this.
第三个最重要的部分link(或者以防万一):
# create a file under app/models (or lib/) to define your abilities (in this example I protect only the HostAppCoolPage model):
Spree::Ability.register_ability MyAppAbility
class MyAppAbility
include CanCan::Ability
def initialize(user)
if user.has_role?('admin')
can manage, :host_app_cool_pages
end
end
end
就我个人而言,我会选择装饰器选项(代码似乎有点不清楚,但在确定谁可以管理什么时更清晰 - 记住 abilities precedence)但这取决于你。如果您有任何具体问题,请随时提出,我会尽可能提供帮助。
编辑:所以如果你想为某些用户禁用身份验证,也许只是利用现有的 Devise 方法?像这样(在你的 user
模型中):
def active_for_authentication?
super && self.am_i_not_a_guest? # check here if user is a Guest or not
end
def inactive_message
self.am_i_not_a_guest? ? Spree.t('devise.failure.invalid') : super # just make sure you get proper messages if you are using that module in your app
end
我使用 STI 向我的 Spree::User 模型 class 添加了继承。我有一个 :type 列,它可以是 (Spree::Guest, Spree::Writer, or Spree::Reader)。
在管理员端的身份验证中,我只想验证作者和 reader。解决此问题的最佳选择是什么?
我试图将创建操作重写为:
def create
authenticate_spree_user!
if spree_user_signed_in? && (spree_current_user.role?(:writer) || spree_current_user.role?(:reader))
respond_to do |format|
format.html {
flash[:success] = Spree.t(:logged_in_succesfully)
redirect_back_or_default(after_sign_in_path_for(spree_current_user))
}
format.js {
user = resource.record
render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
}
end
else
flash.now[:error] = t('devise.failure.invalid')
render :new
end
end
在这种情况下,当尝试使用 :guest 类型的用户进行身份验证时,它会重定向到带有无效失败消息的新操作 (ok),但用户会以某种方式通过身份验证 (nok)。
我认为这不是解决问题的好方法,控制器应该只是一个控制器。我宁愿走那条路:
Spree 使用 cancancan (or cancan in older branches) for authorization and that's how Spree implements that。我不知道你为什么想要那个 STI 解决方案 - 我只是为此创建新的自定义 Spree::Role
但正如我所说我不知道你为什么选择 STI 方式 - 这应该也能正常工作。
无论如何,您可以为该能力文件添加一个装饰器,并额外检查 user.is_a? Spree::Guest
等,或者通过 register_ability
注册新能力 - 例如 this.
第三个最重要的部分link(或者以防万一):
# create a file under app/models (or lib/) to define your abilities (in this example I protect only the HostAppCoolPage model):
Spree::Ability.register_ability MyAppAbility
class MyAppAbility
include CanCan::Ability
def initialize(user)
if user.has_role?('admin')
can manage, :host_app_cool_pages
end
end
end
就我个人而言,我会选择装饰器选项(代码似乎有点不清楚,但在确定谁可以管理什么时更清晰 - 记住 abilities precedence)但这取决于你。如果您有任何具体问题,请随时提出,我会尽可能提供帮助。
编辑:所以如果你想为某些用户禁用身份验证,也许只是利用现有的 Devise 方法?像这样(在你的 user
模型中):
def active_for_authentication?
super && self.am_i_not_a_guest? # check here if user is a Guest or not
end
def inactive_message
self.am_i_not_a_guest? ? Spree.t('devise.failure.invalid') : super # just make sure you get proper messages if you are using that module in your app
end