Devise - аутентифицировать пользователя (после проверки) в действии создания - PullRequest
1 голос
/ 15 декабря 2011

Используя Devise, я знаю, как защитить действия контроллера от не авторизованных пользователей с помощью:

before_filter :authenticate_user!

Чтобы проиллюстрировать то, чего я пытаюсь достичь, см. Пример:

У меня есть следующий контроллер: (проект принадлежит пользователю)

projects_controller.rb

def create
  @project = current_user.projects.new(params[:project])
  if @project.save
    redirect_to @project
  else
    render :action => 'new'
  end
end

Мне нужен способ, с помощью которого пользователи могут больше взаимодействовать свеб-сайт перед тем, как зарегистрироваться / войти. Что-то вроде:

after_validation :authenticate_user!

, если пользователь не вошел в систему, и перенаправить его после успеха (зарегистрироваться / войти) на страницу проекта «Project».

То, что я подумал:

1.) Измените контроллер, чтобы принять объект проекта без user_id, запросите аутентификацию, если пользователь не вошел в систему, затемобновить атрибуты с помощью user_id

Сначала я пытаюсь сделать это так, и это приводит к очень уродливому коду.(Более того, authenticate_user! Не перенаправляет на @project, что приводит к дополнительной настройке)

2.) Создайте мастер с помощью nested_attributes (форма проекта и вложенная новая форма регистрации и форма сеанса)

3.) Что-то лучше?(пользовательский метод?)

Кажется, что authologic справляется с этим легче.Я не уверен, что это повод для перехода, поэтому я хотел бы получить вашу идею / ответ на этот вопрос.Спасибо!

РЕДАКТИРОВАТЬ

ссылки: Peter Ehrlich ответить на комментарий

КОНТРОЛЛЕР С ЛОГИКОЙ ВАЛИДАЦИЙ

projects_controller.rb

def create
  unless current_user
    @project = Project.new(params[:project]) # create a project variable used only for testing validation (this variable will change in resume project method just before being saved)
    if @project.valid? # test if validations pass
      session['new_project'] = params[:project]
      redirect_to '/users/sign_up'
    else
      render :action => 'new'
    end
  else
    @project = current_user.projects.new(params[:project])
    if @project.save
      redirect_to @project
    else
      render :action => 'new'
    end
  end
end

def resume_project
  @project = current_user.projects.new(session.delete('new_project')) # changes the @project variable
  @project.save
  redirect_to @project
end

маршрутов

  get "/resume_project", :controller => 'projects', :action => 'resume_project'

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery

  def after_sign_in_path_for(resource)
    return '/resume_project' if session['new_project'].present?
  super
end

Ответы [ 2 ]

3 голосов
/ 24 декабря 2011

Примерно так должно работать:

def create
    unless current_user
        session['new_project'] = params[:project]
        redirect_to '/register'
        return
    end
    # and on to normal stuff

# in your devise controller 
def after_sign_in_path
    return '/resume_project' if session['new_project'].present?
    super
end

# back in projects_controller now   
def resume_project
    @project.create(session.delete('new_project'))
    # you know the drill from here
    # I'd also put in a check to make an error if the session is not set- in case they reload or some such

Имейте в виду, что сессия - это cookie в браузере, и, следовательно, имеет ограничение размера (4 КБ).Если вы публикуете изображения или другие медиафайлы, вам придется временно хранить их на стороне сервера.

Другим вариантом будет создание проекта без прав пользователя и использование аналогичного метода, позволяющего им требовать его каких собственный.Было бы неплохо, если бы вы хотели, чтобы невостребованные проекты, отображаемые для всех, были доступны в виде потока.

0 голосов
/ 15 декабря 2011

Я не проверял его, но должна быть возможность сохранить действие, которое собирался выполнить пользователь, т.е. создать, с хэшем params, который был отправлен, и перенаправить на него после успешного входа. Затем он будет обрабатывать случаи ошибок как обычно.

Вы пробовали это?

...