设计 - 在创建操作上对用户进行身份验证(经过验证)

时间:2011-12-15 02:28:54

标签: ruby-on-rails validation authentication devise before-filter

使用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!

如果用户未登录,则在成功(注册/登录)后将其重定向到“项目”显示页面。

我想的事情:

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 个答案:

答案 0 :(得分:3)

这样的事情应该有效:

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,因此具有大小限制(4kb)。如果您要发布图像或其他媒体,则必须在服务器端临时存储它们。

另一个选择是创建一个无用户项目,并使用类似的技术允许他们将其声明为自己的项目。如果您希望无人认领的项目显示为全部可用作流程,那将是很好的。

答案 1 :(得分:0)

我还没有对其进行测试,但应该可以存储用户要执行的操作,即。使用提交的params哈希创建,并在成功登录后重定向到它。然后它将正常处理错误情况。

你试过吗?