0

我使用 STI 向我的 Spree::User 模型类添加了继承。我有一个 :type 列,它可以是(Spree::Guest、Spree::Writer 或 Spree::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)。

4

1 回答 1

1

我认为这不是解决这个问题的好方法,控制器应该只是一个控制器。我宁愿走那条路:

Spree 使用cancancan(或旧分支中的 cancan)进行授权,这就是Spree 实现的方式。我不知道你为什么想要那个 STI 解决方案——我只是为此创建新的自定义Spree::Role,但正如我所说,我不知道你为什么选择 STI 方式——这也应该可以正常工作。无论如何,您可以只为该能力文件添加一个装饰器,并对诸如此类的内容进行额外检查,或者通过- 类似这样user.is_a? Spree::Guest的内容注册新能力。register_ability

第三个链接最重要的部分(或者如果它关闭):

# 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

就我个人而言,我会选择装饰器选项(代码似乎有点不清楚,但在确定可以由谁管理的内容时更清晰 - 请记住能力优先级),但这取决于你。如果您有任何具体问题,请随时提出,如果可以,我会提供帮助。

编辑:因此,如果您想为某些用户禁用身份验证,也许只是利用现有的设计方法?像这样的东西(在你的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
于 2015-07-14T12:59:51.180 回答