Разрешить анонимному / гостевому пользователю "опробовать" функциональность без регистрации в приложении Rails / Devise / CanCan - PullRequest
5 голосов
/ 22 марта 2011

Я занимаюсь разработкой приложения на Rails 3 с использованием Devise и CanCan.

Приложение позволяет анонимным (не зарегистрированным) пользователям получать доступ к некоторым приложениям, а зарегистрированным пользователям - другие части.

Один из аспектов приложения (приложение для тренировки йоги) состоит в том, что пользователи могут создавать последовательности йоги, связывая воедино позы йоги, а затем воспроизводить их в видеоплеере.

В настоящее время у меня есть все функции длязарегистрированные пользователи, но теперь они хотят, чтобы анонимные пользователи могли создавать последовательность и воспроизводить ее, но для того, чтобы «сохранить» ее (т. е. снова использовать в любой последующей сессии), им необходимо зарегистрироваться.

В настоящее время для этого требуется фактическое создание экземпляра модели Sequence, который принадлежит пользователю (упрощенно ниже)

class Sequence < ActiveRecord::Base

  validates_presence_of :name
  validate :status_must_be_private_if_user_nil

  # Associations
  has_many :ordered_asana_sequences, :class_name => "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

Но, конечно, у анонимных пользователей нет модели User.

Я что-то взломал, когда Последовательности ДОЛЖНЫ принадлежать Пользователям, но это не обязательно (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) может редактировать любые последовательности других анонимных пользователей.Который, я думаю, не конец света, но я бы предпочел, чтобы он был более безопасным.

Вот потенциальные способы, которыми я думал сделать это:

'Зарегистрируйте «анонимных пользователей»

  • Если гостевой пользователь собирается создать последовательность, сгенерируйте адрес электронной почты и пароль и «зарегистрируйте» этого «гостевого» пользователя.Затем назначьте новую модель последовательности этому новому пользователю.Если пользователь решает зарегистрироваться в режиме реального времени, просто обновите существующую запись пользователя новым адресом электронной почты и паролем.
  • Преимущества: Очень мало изменений в существующем приложении - нужно только разобраться с ним впроцесс "регистрации".
  • Недостатки: может привести к большому количеству мертвых учетных записей пользователей, которые мне нужно смести после

Не сохраняйтеУпорядочить, но сериализовать и сохранить в сеансе

  • Если пользователь-гость собирается создать последовательность, когда он хочет ее «сохранить», снимите ее в метод контроллера, который сериализует модель исохраняет его в сеансе.Затем проигрыватель Sequence и, я полагаю, редактор последовательностей могут при желании извлечь его из сеанса вместо хранилища данных
  • Преимущества: Нет необходимости создавать учетные записи для гостей, поэтому нет необходимостиочистки.Не нужно заниматься модификацией Способностей, так как гость будет получать модели не из хранилища данных, а из их сеанса.
  • Недостатки: Кажется хакерским.Потребуется много точек соприкосновения в приложении, чтобы определить, откуда взять последовательность.Более высокий потенциал для ошибок

Придумайте другой способ назначить Последовательность гостевому пользователю, кроме создания user_id nil

  • Преимущества: Это будет блестяще
  • Недостатки: Понятия не имею, что делать.

Я надеюсь, что есть кое-что, чего я не видел в Devise (можно пригласить,может быть?) это было бы чище, чем самому кататься.

Или у кого-нибудь есть предложения по этой проблеме?Это кажется довольно распространенным требованием, но не смог найти каких-либо указаний.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 24 марта 2011

Во введении Райана в CanCan он предлагает следующее предложение:

Создайте объект нового пользователя в памяти для гостевых пользователей на сайте, но не сохраняйте его.Таким образом, все ваши функции, которые необходимо связать с пользователем, будут по-прежнему работать, но они не сохранятся.

См. Railscast здесь: http://railscasts.com/episodes/192-authorization-with-cancan

Пример кода Райана:

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? и отобразить другую кнопку «сохранить» для зарегистрированных пользователей и гостей.

Вы можете сделать это довольно просто (избегая хранения этого в сеансе и т. Д.), Предоставив скрытую форму регистрации учетной записи на странице создания последовательности.Затем просто нажмите кнопку «Сохранить», чтобы гости открывали форму создания учетной записи, и, когда они отправляют эту форму, они одновременно отправляют регистрацию пользователя и создание последовательности.

Затем все ваши последовательности # создаютдействие, которое нужно выполнить, выглядит примерно так:

...
current_user.update_attributes(params[:user]) if current_user.new_record?

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

Вам нужно превратить это в рабочий код, но я уверен, что основная идея сработает.

Удачи!

3 голосов
/ 05 июня 2011

Я также работаю над проектом rails 3 с / devise и cancan. Мои потребности немного отличаются тем, что мне нужно сохранить активность анонимных пользователей в БД (не нужно подметать). Вот что я сделал для входа анонимного пользователя. Надеюсь, это поможет.

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
...