Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make modular helper in Sinatra

i want to make a method inside a module (for grouping reason) that can be called as a module.method, something like this:

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

but when i try to call it using UserSession.logged_in? it said that logged_in is not UserSession's method

undefined method `logged_in?' for UserSession:Module

when i move the method as UserSession's method:

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

it gives an error, that i could not access the session variable

undefined local variable or method `session' for UserSession:Module

what is the best solution for this problem?

like image 987
Kokizzu Avatar asked Aug 21 '13 08:08

Kokizzu


2 Answers

You can use a different convention for the helpers method.

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

The module definition can of course be in another (required) file.

Behind the scenes, helpers <Module> is doing an include, but not simply into the Sinatra application sub-class you are using for your app. The include needs to be made compatible with how get, post etc work their magic, and helpers does that for you.

like image 163
Neil Slater Avatar answered Nov 07 '22 20:11

Neil Slater


nevermind, i found the answer, i have tried define_method('UserSession.logged_in?') also, but no luck

last thing i've tried is:

# 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

but something must be called first

before // do
  UserSession.new session
end

then it can be used as desired:

get '/' do
  if UserSession.logged_in?
    # do something here
  end
end
like image 2
Kokizzu Avatar answered Nov 07 '22 19:11

Kokizzu