Абстракция контроллера Padrino

Я пробовал фреймворк Padrino в одном из своих проектов, и есть одна вещь, которая меня очень раздражает. Я хочу, например, реализовать процесс регистрации пользователя с использованием OmniAuth и хочу разбить обработчик запросов (действие контроллера) на отдельные методы, например:

get ":provider/callback" do
  @user = find_the_user_by_oauth(request)
  create_user unless @user
  store_user_in_session
end

def find_the_user_by_oauth(request)
  #...
end

def store_user_in_session
  session[:user_id] = @user.id
end

Я знаю, что было бы лучше перенести логику на уровень модели, но мой вопрос в том, как я могу разбить логику контроллера на отдельные методы и обмениваться информацией между ними (например, используя переменные экземпляра). В Rails я создал эти методы в приватной области своего контроллера, но здесь я должен расширить класс Application, потому что он вызывает исключение метода Undefined для предыдущего кода. Я пробовал помощники, но помощники не знают переменных экземпляра, поэтому вы должны передавать переменные каждый раз.

Каков хороший способ сделать мои действия контроллера чистыми в Padrino?


person Nucc    schedule 11.11.2012    source источник


Ответы (2)


Чтобы определить метод внутри контроллера Padrino, вы можете использовать define_method вместо def.

Для вашего примера сделайте что-то вроде этого:

Admin.controllers :dummy do

  define_method :find_the_user_by_oauth do |request|
    request.params["username"]
    # ...
  end

  define_method :store_user_in_session do
    session[:user_id] = @user
  end

  get :test do
    @user = find_the_user_by_oauth(request)
    create_user unless @user
    store_user_in_session()
    session.inspect
  end

end

Падрино запускает блок, отправленный Admin.controllers, используя instance_eval. См. этот ответ для различий https://stackoverflow.com/a/3171649 между define_method и def

person lz.    schedule 21.02.2013

возможный оффтоп, но не могли бы вы вместо этого использовать Espresso Framework.

тогда вы сможете решить свою проблему так же просто, как:

class App < E

  def index provider, action = 'callback'
    @user = find_the_user_by_oauth
    create_user unless @user
    store_user_in_session
  end

  private

  def find_the_user_by_oauth
    # provider, action are accessed via `action_params`
    # action_params[:provider]
    # action_params[:action]
  end

  def store_user_in_session
    session[:user_id] = @user.id
  end

end
person alfred jon    schedule 11.11.2012
comment
Я не хочу использовать другой фреймворк. Поддержка Padrino хорошая, я хотел бы использовать драгоценные камни, которые полностью совместимы с моей структурой, и я думаю, что с Espresso у меня возникнут некоторые неожиданные проблемы. - person Nucc; 11.11.2012
comment
конечно, вам решать, я не настаиваю, это было просто невинное предложение. - person alfred jon; 11.11.2012
comment
ммм, что вы подразумеваете под неожиданными проблемами? Эспрессо так же прост, как Руби. Пользуюсь около 2х месяцев, проблем и сюрпризов пока не было. Отличная документация, которая на самом деле редко нужна, потому что все сделано в стиле Ruby. - person alfred jon; 11.11.2012
comment
Обычно для популярных гемов кто-то создает специальную версию фреймворка, чтобы его было проще интегрировать в фреймворк. Я не знаю Espresso и не знаю, сколько непредвиденных проблем у меня возникнет, когда гем не полностью совместим с эспрессо, и я не смогу использовать один из гемм, специфичных для фреймворка mygemname-espresso (например, гем omniauth-padrino с padrino). ). - person Nucc; 11.11.2012