in Rails: recupera l'input dell'utente da un modulo non associato a un modello, usa il risultato nel controller

StackOverflow https://stackoverflow.com/questions/106711

  •  01-07-2019
  •  | 
  •  

Domanda

Ecco una versione semplificata di ciò che sto cercando di fare:

  1. Prima di eseguire qualsiasi altra azione, presentare all'utente un modulo per recuperare una stringa.
  2. Immettere la stringa, quindi reindirizzare all'azione del controller predefinita (ad es. indice). La stringa deve solo esistere, non sono necessarie altre convalide.
  3. La stringa deve essere disponibile (come variabile di istanza?) per tutte le azioni in questo controller.

Sono molto nuovo con Rails, ma questo non sembra che dovrebbe essere estremamente difficile, quindi mi sento un po 'stupido.

Cosa ho provato: Ho un before_filter che reindirizza a un metodo privato che assomiglia a

def check_string
  if @string
    return true
  else
    get_string
  end
end

il metodo get_string sembra

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

Questo non riesce perché ho due chiamate di rendering o di reindirizzamento nella stessa azione. Posso eliminare il primo respond_to , ovviamente, ma ciò che accade è che il controller viene intrappolato nel metodo get_string . Posso vedere più o meno perché ciò sta accadendo, ma non so come risolverlo e scoppiare. Devo essere in grado di mostrare un modulo (Visualizza), ottenere e quindi fare qualcosa con la stringa di input, quindi procedere normalmente.

Il file get_string.html.erb sembra

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

Sarò grato per qualsiasi aiuto!

Modifica

Grazie per le risposte ...
@Laurie Young: hai ragione, avevo frainteso. Per qualche ragione avevo in mente che l'istanza di un determinato controller invocato da un utente sarebbe persistita per tutta la sessione e che parte della magia di Rails era nel tracciamento degli oggetti associati a ciascuna sessione dell'utente. Riesco a capire perché questo non ha molto senso in retrospettiva e perché il mio tentativo di utilizzare una variabile di istanza (che pensavo potesse persistere) non funzionerà. Grazie anche a te :)

È stato utile?

Soluzione

Parte del problema è che non stai impostando @string. Per questo non hai davvero bisogno del filtro pre-filtro e dovresti essere in grado di usare:

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

Se vuoi che la variabile @string sia disponibile per tutte le azioni, dovrai memorizzarla nella sessione.

Altri suggerimenti

Mi sembra che manchi un concetto di binari. Ogni singola pagina che l'utente vede è una richiesta diversa.

Potrei aver capito male cosa stai cercando di fare. Ma mi sembra che tu voglia vedere due pagine

  1. Nella prima pagina hanno impostato una variabile stringa
  2. Nella seconda pagina vedono una pagina che dipende in qualche modo dal set di variabili

Il modo migliore per farlo sarebbe quello di avere un filtro precedente che controlla l'esistenza del varibale e, se non è impostato, reindirizza a loro al modulo e continua altrimenti

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

Questa è l'idea di base alla base del funzionamento dei plugin come RestfulAuthentication. In tal caso " stringa " è un token di accesso (credo che l'ID utente) sia archiviato nella sessione.

Se dai un'occhiata all'azione login_required 'in authenticated_system.rb` da ResultfulAuth: lo fa sostanzialmente, anche se ha qualche correzione in più, altre cose aggiunte in

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top