允许匿名/来宾用户“试用”function,而无需在Rails / Devise / CanCan应用程序中注册

我正在使用Devise和CanCan开发一个Rails 3应用程序。

该应用程序允许匿名(未注册)用户访问某些应用程序,并允许注册用户访问其他部分。

应用程序(瑜伽锻炼应用程序)的一个方面是用户可以通过将瑜伽姿势串联起来创建瑜伽序列,然后他们可以在video播放器中播放它们。

我目前已经为注册用户提供了所有function,但是现在希望允许匿名用户能够创建序列并播放它,但要“保存”它(即能够在任何后续会话中再次使用它) ,他们需要注册。

目前,这需要实际创建一个属于用户的Sequence模型实例(简化如下)

class Sequence  "OrderedAsanaSequence", :order => 'position ASC', :dependent => :destroy has_many :asanas, :through => :ordered_asana_sequences belongs_to :user def status_must_be_private_if_user_nil errors.add(:status, "must be private is user is nil") if user == nil and status != :private end end 

但是,当然,匿名用户没有用户模型。

我有点在Hackces属于用户的东西,但它不是强制性的(user_id可以是nil,如上所示),并且通过CanCan保护编辑的能力:

 class Ability {snip} # A guest can play with creating sequences can :create, [Sequence] # A guest can edit/update their own Sequences can :update, [Sequence], :user_id => user.id end 

但是,这意味着任何匿名用户(user_id = nil)都可以编辑任何其他匿名用户的序列。 其中,我想这不是世界末日,但我希望它更安全。

以下是我想到的潜在方法:

‘注册’匿名用户

  • 如果访客用户去创建序列,则生成电子邮件和密码并“注册”此“访客”用户。 然后将新序列模型分配给此新用户。 如果用户决定注册真实,只需使用新的电子邮件和密码更新现有用户记录。
  • 优点:对现有应用程序的更改很少 – 只需要在“注册”过程中处理它。
  • 缺点:最终可能会有大量死用户帐户,我需要清理它们

不要持久化序列,而是将其序列化并将其存储在会话中

  • 如果访客用户去创建序列,当他们想要“保存”它时,将其拍摄到控制器方法,该方法序列化模型并将其存储在会话中。 然后,序列播放器,我猜,序列编辑器可以选择从会话而不是数据存储中拉出它
  • 优点:不为guest虚拟机创建用户帐户,因此无需清理。 无需处理修改function,因为访客不会从数据存储中获取模型,而是从他们的会话中获取模型。
  • 缺点:看似hacky。 应用程序中需要很多接触点来确定从哪里获取序列。 错误的可能性更高

找出将一个Sequence分配给guest用户的其他方法,然后将user_id设为nil

  • 优点:它将是辉煌的
  • 缺点:不知道该怎么做。

我希望有一些我没有在Devise中看到过的东西(也许是可邀请的),这些东西比我自己更清洁。

或者,是否有人对此问题有任何建议? 这似乎是一个相对常见的要求,但无法发掘任何指导。

谢谢!

在Ryan对CanCan的介绍中,他提出了以下建议:

在内存中为访客用户创建一个新用户对象,但不保存它。 这样,需要与用户关联的所有函数仍然可以工作,但它们不会保存。

请参阅此处的railscast: http ://railscasts.com/episodes/192-authorization-with-cancan

Ryan的代码示例是:

 class Ability include CanCan::Ability def initialize(user) user ||= User.new # This initializer is creating your memory-only guest users if user.role? :admin can :manage, :all else can :read, :all can :create, Comment can :update, Comment do |comment| comment.try(:user) == user || user.role?(:moderator) end if user.role?(:author) can :create, Article can :update, Article do |article| article.try(:user) == user end end end end end 

那么,在您的应用中,如果您使用此方法,那么在您的视图中,您可以检查current_user.new_record? ,并为注册用户与来宾呈现不同的“保存”按钮。

您可以通过在序列创建页面上提供隐藏的帐户注册表单来使这非常简单(避免将其存储在会话等中)。 然后只需让客人的“保存”按钮显示帐户创建表单,当他们提交该表单时,他们同时提交用户注册和序列创建。

然后你需要做的所有序列#create动作都是这样的:

 ... current_user.update_attributes(params[:user]) if current_user.new_record? if current_user.sequences.create(params[:sequence]) redirect_to ... else render ... end ... 

你需要把它变成工作代码,但我相信基本的想法会起作用。

祝好运!

我也正在开发一个带有设计和cancan的rails 3项目。 我的需求有点不同,因为我需要在数据库中保持匿名用户的活动(不需要扫描)。 这是我在匿名用户中所做的工作。 希望这可以帮助。

 def sign_in_anonymous_user unless user_signed_in? user = User.new role = "anonymous" user.confirmed_at = Time.now-1.minute user.save :validate => false sign_in :user, user end end