简体   繁体   English

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

[英]in Rails : Retrieve user input from a form that isn't associated with a Model, use the result within the controller

Here's a simplified version of what I'm trying to do :这是我正在尝试做的事情的简化版本:

  1. Before any other actions are performed, present the user with a form to retrieve a string.在执行任何其他操作之前,向用户提供一个表单来检索字符串。
  2. Input the string, and then redirect to the default controller action (eg index).输入字符串,然后重定向到默认的控制器动作(例如索引)。 The string only needs to exist, no other validations are necessary.字符串只需要存在,不需要其他验证。
  3. The string must be available (as an instance variable?) to all the actions in this controller.该字符串必须可用于此控制器中的所有操作(作为实例变量?)。

I'm very new with Rails, but this doesn't seem like it ought to be exceedingly hard, so I'm feeling kind of dumb.我对 Rails 很陌生,但这似乎并不应该非常困难,所以我感觉有点傻。

What I've tried : I have a before_filter redirecting to a private method that looks like我试过的:我有一个before_filter重定向到一个私有方法,看起来像

def check_string
  if @string
    return true
  else
    get_string
  end
end

the get_string method looks like 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

This fails because i have two render or redirect calls in the same action.这失败了,因为我在同一个操作中有两个渲染或重定向调用。 I can take out that first respond_to , of course, but what happens is that the controller gets trapped in the get_string method.当然,我可以取出第一个respond_to ,但是会发生控制器被困在get_string方法中的情况。 I can more or less see why that's happening, but I don't know how to fix it and break out.我或多或少能明白为什么会这样,但我不知道如何解决它并爆发。 I need to be able to show one form (View), get and then do something with the input string, and then proceed as normal.我需要能够显示一个表单(视图),获取然后对输入字符串执行某些操作,然后照常进行。

The get_string.html.erb file looks like 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 %>

I'll be thankful for any help!我会感谢任何帮助!

EDIT编辑

Thanks for the replies...感谢您的回复...
@Laurie Young : You are right, I was misunderstanding. @Laurie Young:你说得对,我误会了。 For some reason I had it in my head that the instance of any given controller invoked by a user would persist throughout their session, and that some of the Rails magic was in tracking objects associated with each user session.出于某种原因,我认为用户调用的任何给定控制器的实例将在整个会话中持续存在,并且 Rails 的一些魔力在于跟踪与每个用户会话关联的对象。 I can see why that doesn't make a whole lot of sense in retrospect, and why my attempt to use an instance variable (which I'd thought would persist) won't work.我可以理解为什么回想起来这没有多大意义,以及为什么我尝试使用实例变量(我认为它会持续存在)不起作用。 Thanks to you as well :)也谢谢你:)

Part of the problem is that you aren't setting @string.部分问题是您没有设置@string。 You don't really need the before_filter for this at all, and should just be able to use:您根本不需要 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

If you want the @string variable to be available for all actions, you will need to store it in the session.如果您希望 @string 变量可用于所有操作,则需要将其存储在会话中。

It looks like me like your missing a rails concept.看起来我就像你缺少一个 rails 概念。 Every single page the user sees is a different request.用户看到的每个页面都是不同的请求。

I might have missunderstood what you are trying to do.我可能误解了你想要做什么。 But it seems to me you want the user to see two pages,但在我看来你希望用户看到两个页面,

  1. In the first page they set a string variable在第一页中,他们设置了一个字符串变量
  2. In the second page they see a page that is somehow dependent on the variable set在第二页中,他们看到一个以某种方式依赖于变量集的页面

The best way to do this would be to have to a before filter that checks for the existance of the varibale, and if its not set, redirects to them to the form, and otherwise continues执行此操作的最佳方法是使用 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

This is the basic idea behind how plugins like RestfulAuthentication work.这是 RestfulAuthentication 等插件工作原理背后的基本思想。 In that case "string" is a login token (the user ID i think), is is stored in the session.在这种情况下,“字符串”是登录令牌(我认为是用户 ID),存储在会话中。

If you take a look at the login_required' action in authenticated_system.rb` from ResultfulAuth: it does basically this, though it has a few more error corrections, other stuff added in如果您查看 ResultfulAuth login_required' action in authenticated_system.rb` 中的login_required' action in :它基本上是这样做的,尽管它还有一些错误更正,还添加了其他内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM