Rails / Devise:优雅地要求用户登录已注销的创建

时间:2014-03-01 17:43:59

标签: ruby-on-rails authentication devise

我正在继续调整Rails Getting Started项目以获得我想要的身份验证行为。

我想控制特定操作级别允许和不允许的内容,而不是整个控制器。例如,您无需登录即可查看帖子(index / show),但您必须登录才能访问该表单以提交新帖子(new并获得已提交的帖子(create)。

由于我希望人们在没有登录的情况下被重定向到登录,并且我将在一百万个地方一遍又一遍地使用该代码段,我将其放在应用程序控制器中:< / p>

def authcheck
    unless user_signed_in?
        redirect_to new_user_session_path
    end
end

对于新帖子,这似乎有效:

def new
    authcheck #see application controller
    @post = Post.new
end

但是对于我打开两个标签并且我在新帖子表单上有第一个标签的情况,但我在第二个标签上注销,然后尝试在第一个表单上提交帖子,我收到一个错误用户为null,即使在我看来它应该被重定向:

def create
    authcheck
    #when not signed in, causes error "undefined method 'posts' for nil:NilClass"
    @post = current_user.posts.new(post_params)

    if @post.save
        redirect_to @post
    else
        render 'new'
    end
end

实际上,我最初收到了一个异常页面,但我在应用程序控制器的exception行中将null_session更改为protect_from_forgery with: :exception

基本上:为什么不重定向到登录页面,就像它只是显示新帖子的表单一样?而且,从那里,你可以建议我应该做些什么呢?

1 个答案:

答案 0 :(得分:0)

我认为我的工作是在假象下。我认为redirect_to是执行的结束。但它似乎没有这样的方式 - 例如,在重定向行之后,我可以将服务器绑定到square the circle,即使它不依赖于吐出网页。

我修改了我的“authcheck”以返回true或false,然后将所有内容放入if块中。第一个例子并没有以旧的方式失败,因为它只是实例化一个新帖子,但是它实际上是否被保存并不重要。

更改为应用程序控制器例程:

def authcheck
    unless user_signed_in?
        redirect_to new_user_session_path
        return false
    end
    return true
end

对帖子控制器例程的更改:

def new
    if authcheck #see application controller
        @post = Post.new
    end
end

def create
    if authcheck
        @post = current_user.posts.new(post_params)
        if @post.save
        redirect_to @post
        else
            render 'new'
        end
    end
end

我怀疑我并不是真的按照公认的方式做事,所以在接受我自己的答案之前,我会坚持几天。 : - )