2013-08-21 11 views
10

voglio fare un metodo all'interno di un modulo (per raggruppare ragione) che può essere chiamato come un module.method, qualcosa di simile:Come rendere aiutante modulare Sinatra

helpers do 
    module UserSession 
    def logged_in? 
     not session[:email].nil? 
    end 
    def logout! 
     session[:email] = nil 
    end 
    end 
end 

ma quando provo a chiamarlo usando UserSession.logged_in? ha detto che login_in non è il metodo UserSession

metodo non definito `logged_in? ' per UserSession: Modulo

quando sposto il metodo come metodo di UserSession:

helpers do 
    module UserSession 
    def self.logged_in? 
     not session[:email].nil? # error 
    end 
    def self.logout! 
     session[:email] = nil 
    end 
    end 
end 

dà un errore, che non ho potuto accedere al session variabile

indefinito variabile locale o metodo `sessione 'per UserSession: Modulo

qual è la migliore soluzione n per questo problema?

+0

'include UserSession'? – shime

+0

quindi, stai insinuando che dovrei creare un modulo al di fuori del metodo dei soccorritori di Sinatra, quindi includerlo? avrà lo stesso problema (non può accedere alla variabile di sessione) – Kokizzu

risposta

5

È possibile utilizzare una convenzione diversa per il metodo helpers.

module UserSession 
    def logged_in? 
    not session[:email].nil? 
    end 
    def logout! 
    session[:email] = nil 
    end 
end 

helpers UserSession 

get '/foo' do 
    if logged_in? 
    'Hello you!' 
    else 
    'Do I know you?' 
    end 
end 

La definizione modulo può naturalmente essere in un altro file (require d).

Dietro le quinte, helpers <Module> sta facendo un include, ma non semplicemente nella sottoclasse dell'applicazione Sinatra che si sta utilizzando per la propria app. Il include deve essere reso compatibile con il modo in cui get, post ecc. Funziona la loro magia e helpers lo fa per te.

+0

no, voglio chiamare anche il metodo con il nome del modulo. 'UserSession.logged_in?' – Kokizzu

+1

@Kokizzu: Potrebbe essere possibile, ma non sono sicuro Quadro Sinatra. Il metodo richiede l'accesso allo stato della richiesta. –

+0

@Kokizzu "voglio chiamare anche il metodo con il nome del modulo .. UserSession.logged_in?" - perché? – iain

2

Nevermind, ho trovato la risposta, ho provato define_method('UserSession.logged_in?') anche, ma senza fortuna

ultima cosa che ho provato è:

# outside helpers 
class UserSession 
    @@session = nil 
    def initialize session 
    @@session ||= session 
    end 
    def self.check 
    throw('must be initialized first') if @@session.nil? 
    end 
    def self.logged_in? 
    self.check 
    not @@session[:email].nil? 
    end 
    def self.logout 
    self.check 
    @@session.delete :email 
    end 
end 

ma qualcosa deve essere chiamato prima

before // do 
    UserSession.new session 
end 

quindi può essere utilizzato a piacere:

get '/' do 
    if UserSession.logged_in? 
    # do something here 
    end 
end 
+1

Se si intende collegare il codice di sicurezza o di proprietà, è consigliabile aggiungere anche un blocco "dopo //" che cancella la variabile di sessione memorizzata. Altrimenti potrebbe persistere nella successiva richiesta sullo stesso processo (nel caso semplice qui sarebbe innocuo, e sovrascritto alla prossima richiesta, ma è un dato di dati rischioso da aggirare). –

+0

sì, questo è davvero un problema .. quando faccio due richieste contemporaneamente, mostra che la vecchia variabile statica non è stata ancora cancellata ..> ___ < – Kokizzu