in Rails: recupera l'input dell'utente da un modulo non associato a un modello, usa il risultato nel controller
-
01-07-2019 - |
Domanda
Ecco una versione semplificata di ciò che sto cercando di fare:
- Prima di eseguire qualsiasi altra azione, presentare all'utente un modulo per recuperare una stringa.
- Immettere la stringa, quindi reindirizzare all'azione del controller predefinita (ad es. indice). La stringa deve solo esistere, non sono necessarie altre convalide.
- 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 :)
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
- Nella prima pagina hanno impostato una variabile stringa
- 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