2013-08-21 3 views
10

я хочу сделать метод внутри модуля (для группирования причины), которую можно назвать как module.method, что-то вроде этого:Как сделать модульный помощник в Синатрах

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

, но когда я пытаюсь вызвать его используя UserSession.logged_in?, он сказал, что logged_in не является методом UserSession

undefined method `logged_in? ' для UserSession: Модуль

, когда я двигаю метод как метод UserSession в:

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

он дает ошибку, что я не мог получить доступ к session переменной

неопределенную локальную переменную или метод `session 'для UserSession: модуль

Что такое лучший solutio n для этой проблемы?

+0

'include UserSession'? – shime

+0

Итак, вы подразумеваете, что я должен сделать модуль вне метода помощников синатра, а затем включить его? он будет иметь ту же проблему (не может получить доступ к переменной сеанса) – Kokizzu

ответ

5

Вы можете использовать другое соглашение для метода 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 

Определение модуль может быть, конечно, в другом файле (require г).

За кулисами helpers <Module> делает include, но не просто в подклассу приложения Sinatra, которое вы используете для своего приложения. include необходимо сделать совместимым с тем, как get, post и т. Д. Работают с их магией, и helpers делает это за вас.

+0

нет, я хочу также вызвать метод с именем модуля .. 'UserSession.logged_in?' – Kokizzu

+1

@Kokizzu: Это может быть возможно, но я не уверен, как внутри Синатра. Метод нуждается в доступе к состоянию запроса. –

+0

@Kokizzu "Я хочу также вызвать метод с именем модуля .. UserSession.logged_in?" - Зачем? – iain

2

фигу, я нашел ответ, я пытался define_method('UserSession.logged_in?') также, но не повезло

последнее, что я попытался это:

# 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 

но что-то должно быть названо первым

before // do 
    UserSession.new session 
end 

тогда он может быть использован по желанию:

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

Если это предназначено для привязки к коду безопасности или собственности, вероятно, вы также должны добавить блок 'after //', который очищает хранимую переменную сеанса. Иначе он вполне мог бы продолжить следующий запрос по тому же самому процессу (в простом случае, который был бы безвредным и переписанным по следующему запросу, но это опасная часть данных, чтобы повесить вокруг). –

+0

Да, это действительно проблема. Когда я делаю два запроса сразу, это показывает, что старая статическая переменная еще не удалена.> ___ < – Kokizzu

Смежные вопросы