在Rails中:从与模型无关的表单中检索用户输入,在控制器中使用结果

时间:2020-03-06 14:28:27  来源:igfitidea点击:

这是我正在尝试做的简化版本:

  • 在执行任何其他操作之前,请向用户提供一个用于检索字符串的表单。
  • 输入字符串,然后重定向到默认的控制器操作(例如index)。该字符串只需要存在,就不需要其他验证。
  • 该字符串必须可用于此控制器中的所有操作(作为实例变量?)。

我对Rails还是很陌生,但这似乎不应该太难,所以我感觉有些愚蠢。

我尝试过的
我有一个before_filter重定向到看起来像的私有方法

def check_string
  if @string
    return true
  else
    get_string
  end
end

get_string`方法看起来像

def get_string
  if params[:string]
    respond_to do |format|
      format.html {redirect_to(accounts_url)} # authenticate.html.erb
    end
  end

  respond_to do |format|
    format.html {render :action =>"get_string"} # get_string.html.erb
  end
end

失败是因为我在同一操作中有两个渲染或者重定向调用。我当然可以取出第一个" respond_to",但是发生的是控制器陷入了" get_string"方法中。我或者多或者少都知道为什么会这样,但是我不知道如何解决它并突破。我需要能够显示一种表单(视图),获取然后对输入字符串进行处理,然后像往常一样进行。

get_string.html.erb文件看起来像

<h1>Enter a string</h1>
<% form_tag('/accounts/get_string') do %>
<%= password_field_tag(:string, params[:string])%>
<%= submit_tag('Ok')%>
<% end %>

我将感谢帮助!

编辑

感谢回覆...
@Laurie Young:我们是对的,我被误解了。由于某种原因,我想起了由用户调用的任何给定控制器的实例将在整个会话期间保持不变,并且某些Rails的魔力在于跟踪与每个用户会话关联的对象。回想起来,我明白了为什么这样做没有太大意义,为什么我尝试使用实例变量(我认为这样会持续存在)不起作用。也感谢你:)

解决方案

问题的一部分是我们没有设置@string。我们实际上完全不需要before_filter,并且应该能够使用:

def get_string
  @string = params[:string] || session[:string] 
  respond_to do |format|
    if @string  
      format.html {redirect_to(accounts_url)} # authenticate.html.erb
    else 
      format.html {render :action =>"get_string"} # get_string.html.erb
    end
  end
end

如果希望@string变量可用于所有操作,则需要将其存储在会话中。

看起来像我,就像我们缺少Rails概念。用户看到的每个页面都是不同的请求。

我可能会误解了我们要做什么。但是在我看来,我们希望用户看到两个页面,

  • 在第一页中,他们设置了一个字符串变量
  • 在第二页中,他们看到一个页面,该页面某种程度上取决于变量集

最好的方法是使用一个before过滤器来检查变量的存在,如果未设置,则将其重定向到表单,否则继续

class MyController < ApplicationController::Base
  before_filter :require_string

  def require_string
    return true if @string #return early if called multiple times in one request
    if params['string'] or session['string']  #depending on if you set it as a URL or session var
      @string = (params['string'] or session['string'])
      return true
    end

    #We now know that string is not set
    redirect_to string_setting_url and return false #the return false prevents any futher processing in this request
  end
end

这是像RestfulAuthentication这样的插件如何工作的基本思想。在这种情况下,"字符串"是一个登录令牌(我认为是用户ID),存储在会话中。

如果我们看一下ResultfulAuth中authenticated_system.rb中的`login_required'操作:它基本上可以做到这一点,尽管它还有一些错误更正,其他内容也已添加到其中。