在Rails中用Sorcery适配simple_discussion的user_signed_in?方法
user_signed_in?方法 当然可以!Simple Discussion gem确实默认依赖Devise的user_signed_in?方法,但我们完全可以基于Sorcery快速实现这个方法,甚至直接把它和Sorcery自带的logged_in?做等价映射。下面是具体的实现步骤:
1. 在ApplicationController中定义user_signed_in?方法
因为Simple Discussion会在控制器和视图中调用这个方法,我们需要把它定义为一个helper方法,确保在整个应用中都能访问到。
打开app/controllers/application_controller.rb,添加以下代码:
class ApplicationController < ActionController::Base # 保留你已有的代码(比如Sorcery的配置、Cancancan的回调等) # 将Devise风格的user_signed_in?映射到Sorcery的logged_in? def user_signed_in? logged_in? end # 让这个方法在视图中也可用 helper_method :user_signed_in? end
2. 检查current_user是否兼容
Simple Discussion同时也会用到current_user来获取当前登录用户。好在Sorcery默认已经提供了current_user方法(前提是你的用户模型是User;如果是其他模型比如Member,可以在Sorcery配置里指定user_class: 'Member',它会自动生成对应的current_member方法,这时你需要额外重写current_user):
如果你的用户模型不是User,添加这段代码:
def current_user current_member # 替换成你的Sorcery用户模型对应的current_xxx方法 end helper_method :current_user
3. 验证功能
完成上面的步骤后,启动你的Rails服务器,测试Simple Discussion的功能:
- 尝试访问讨论区页面,确认未登录时的权限控制是否正常(比如不能发帖)
- 登录后检查是否能正常使用发帖、评论等功能
- 可以在视图中直接调用
<%= user_signed_in? %>,验证它是否正确返回当前登录状态
为什么这样可行?
Sorcery的logged_in?方法和Devise的user_signed_in?逻辑完全一致:都是判断当前会话中是否存在已登录的用户。我们只是给Simple Discussion提供了它熟悉的方法名,内部还是用Sorcery的认证逻辑,完美适配。
另外,结合Cancancan使用时,只要你的Ability类中正确使用了current_user(或你重写后的版本),权限控制也会正常工作。
内容的提问来源于stack exchange,提问作者Robles Rodolphe

