Что на самом деле делает Sinatra :: Base.condition? - PullRequest
6 голосов
/ 21 января 2012

Я сталкивался с методом синатры условие и был озадачен тем, как он работает.

У меня есть код:

def auth user
  condition do
    redirect '/login' unless user_logged_in?
  end
end

Который проверяет, зарегистрирован ли пользователь для определенных маршрутов, пример маршрута:

get '/', :auth => :user do
  erb :index
end

Метод user_logged_in? определен в файле помощника в каталоге lib проекта:

def user_logged_in?
  if session[:user]
    @user = session[:user]
    return @user
  end 
  return nil 
end

Итак, вопрос в следующем: Как блок condition узнает, что содержит session[:user], когда на маршруте get '/' session[:user] даже не установлен?

Метод condition определен на следующей странице GitHub: Метод базового условия sinatra Спасибо.

Ответы [ 2 ]

4 голосов
/ 22 января 2012

Когда вы определяете маршрут, ключом каждого члена хэша опций является , вызываемый как метод, со значением, передаваемым в качестве аргументов .

Так, когда вы делаете get '/', :auth => :user do ... метод auth вызывается с аргументом :user.Это, в свою очередь, вызывает метод condition с блоком.

Метод condition на самом деле определен чуть выше, где вы ссылаетесь на , что является использованием Это.Он выглядит следующим образом:

def condition(name = "#{caller.first[/`.*'/]} condition", &block)
  @conditions << generate_method(name, &block)
end

Метод generate_method преобразует блок в метод с заданным именем, а затем этот метод сохраняется в массиве @conditions.Содержимое @conditions затем сохраняется с определением маршрута, а @conditions очищается и готово к следующему определению маршрута.

В этот момент блок кода, переданный в condition hasn 'т был казнен.Фактически он был сохранен на потом.

Когда поступает фактический запрос, если путь запроса совпадает с маршрутом, тогда выполняется каждое условие, связанное с этим маршрутом , чтобы проверить, что оновыполнено.В этом примере это когда впервые выполняется redirect '/login' unless user_logged_in?, поэтому session будет настроен и session[:user] будет доступен (или нет, если они не вошли в систему).

Важно понимать, что когда вы передаете блок методу, код в этом блоке не обязательно вызывается сразу.В этом случае код в блоке вызывается только при поступлении фактического запроса.

2 голосов
/ 22 января 2012

Поскольку Синатра отвечает за вызов как методов условия, так и методов маршрута.Поэтому следует с уверенностью предположить, что все, что установлено при выполнении вашего метода маршрута, также устанавливается и при выполнении вашего условия.

Посмотрите на код, начинающийся с здесь : условия называются равными единице.одним;если все условия совпадают, то вызывается блок.Ничего особенного не происходит между проверкой условий и вызовом блока: они в основном выполняются в одном контексте.

...