4

我正在使用带有 Rails 的 Devise 进行用户登录。这一切都很好,但是,我无法让特定的重定向工作。

我是 Rails 新手,所以我做事的方法可能不正确。

本质上,举个例子,我允许用户喜欢一个帖子。但是,他们需要登录才能这样做。我在我的控制器中创建了一个名为“like”的操作,并且控制器具有设计过滤器

before_filter :authenticate_user!, :except => [:index, :show]

输入,从而显示登录页面。一旦用户登录,我想将他们重定向回他们喜欢的帖子,并调用了“喜欢”操作。

我的控制器看起来像

def like

  @post = Post.find(params[:id]) 
  @like = Like.new;
  @like.user_id = current_user.id;
  @like.post_id = params[:id];
  respond_to do |format|
    if @like.save
      format.html { redirect_to @post, notice: 'You have like this post' }
      format.json { head :no_content }
    else 
      format.html { redirect_to @post, notice: 'Sorry you like was not saved  } 
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end  
end 

自然,我不能使用 after_sign_in_path_for 对路径进行硬编码

def after_sign_in_path_for(resource)    
  #path to somewhere
end

但我已经读到我可以使用会话变量,也许可以在上面的代码中调用它。我可以在 Rails 的哪个部分编写会话变量,因为它在控制器操作中为时已晚(因为设计在它遇到类似操作之前接管)并且我看不到如何在视图中设置它。

我的链接也看起来像

<%= link_to "Like", {:controller => :posts, :action => :like, :id => @post.id}, {:method => :post } %> |

PS 使用创建新“帖子”时的重定向工作正常,即用户登录并被重定向到新的帖子视图。

任何帮助和提示将不胜感激。

谢谢

4

2 回答 2

3

您遇到这种情况是因为点赞操作是专门为 POST 设计的。因此,您应该确保用户在POST 到该 URL之前已登录,并且使用 session 执行此操作很棘手:

  • 您必须通过将其排除在外来取消保护类似的方法before_filter
  • 然后手动检查是否user_signed_in?(请注意,这是一个辅助方法),
  • 然后(如果用户未登录),在会话中存储您喜欢的内容并重定向到带有返回 URL 的登录页面
  • 在用户访问此返回 URL(它将是GET而不是POST)时,您必须查找会话信息并执行原始 Like 应该执行的操作(但届时用户将登录)。

看到所有这些舞蹈都将以GET请求结束,为什么不首先对 GET 请求进行 Like 操作以及在查询字符串中传递参数呢?它将需要 0 次代码更改,并且不会让您面临安全威胁,因为 Like 受 before_filter 保护。您只需要通过在标签上使用rel="nofollow"来确保搜索引擎不会跟踪您的 Like 链接。<a>

有关相关讨论,请参阅redirect_to 在 rails 中使用 POST。在那里,其中一个建议是通过 JavaScript 在客户端上构建和提交表单。一旦用户通过身份验证,这将必须在返回 URL 视图上发生。如果您反对将您的类似操作公开为 GET(这违反了 REST 原则),这可能是最好的折衷方案

于 2012-11-22T03:17:17.517 回答
0

这很容易解决:

进入应用程序控制器:

 # after login redirect
 after_filter :store_location

 def store_location
   # previous url save when its not a admin or user url
   session[:previous_url] = request.fullpath unless request.fullpath =~ /\/users/ || request.fullpath =~ /\/admin/ || request.fullpath =~ /\/admin\/login/ || 
   request.fullpath =~ /\/login/
 end
于 2013-10-08T13:33:36.600 回答