Доступ к области Синатры из другого класса - PullRequest
2 голосов
/ 04 апреля 2011

Я запускаю приложение Sinatra с несколькими дополнительными классами, задействованными для создания пользователя, и несколькими другими на лету (без БД, оно поступает из веб-службы). Я пытаюсь отправить флеш-уведомление (используя https://github.com/nakajima/rack-flash) из моей модели User, но не могу понять, как получить доступ к методу / переменной flash, потому что я вне области.

Что-то вроде:

class User
  def something
    if true
      flash[:notice] = 'Good job'
    else
      # nope
    end
  end
end

Что требуется в приложении Sinatra простым require 'models/user'

Ответы [ 2 ]

2 голосов
/ 05 апреля 2011

Это проблема XY [1].Sinatra отвечает за отправку флеш-сообщений, а не ваших пользовательских объектов, поэтому код для установки флеш-памяти должен быть в вашем приложении Sinatra, а не в вашем пользовательском классе.

[1] http://www.perlmonks.org/index.pl?node_id=542341

1 голос
/ 05 апреля 2011

Вы не должны просить своего пользователя (модель) общаться с пользовательским интерфейсом (просмотр).Это плохо / не MVC-чистый.Для этого и нужен контроллер.

Вы можете использовать либо возвращаемые значения, исключения, либо throw/catch (что не является обработкой исключений) для передачи информации из вашей модели в контроллер.Например, используя возвращаемые значения:

post "/create_user" do
  flash[:notice] = case User.something
    when User   then "User Created!"
    when :nono  then "That's not allowed"
    when :later then "User queued to be created later."
  end
end

class User
  def self.something
    if authorized
      if can_create_now
        new(...)
      else
        queue_create(...)
        :later
      end
    else
      :nono
    end
  end
end

Поскольку я упомянул их выше, ниже приведены примеры использования throw / catch и begin / rescue (исключения).Поскольку целесообразность использования любой из этих конструкций сомнительна, давайте уделим минутное молчание, чтобы подумать, если это хорошая идея.


Вот пример использования throw / catch :

post "/create_user" do
  result = catch(:msg){ User.something }
  flash[:notice] = case 
    when :nono  then "That's not allowed"
    when :later then "User queued to be created later."
    else             "User Created!"
  end
end

class User
  def self.something
    throw :msg, :nono unless authorized
    if can_create_now
      new(...)
    else
      queue_create(...)
      throw :msg, :later
    end
  end
end

Наконец, вот пример использования исключений , хотя я не уверен, что это будет уместно для всех (не катастрофических) случаев, когда вы хотите прошить уникальныесообщения пользователю:

post "/create_user" do
  flash[:notice] = "User Created!" # Assume all good
  begin
    User.something
  rescue User::Trouble=>e
    flash[:notice] = case e
      when Unauthorized  then "That's not allowed"
      when DelayedCreate then "User queued to be created later."
      else                    "Uh...Something bad happened."
    end
  end
end

class User
  class Trouble < RuntimeError; end
  class Unauthorized  < Trouble; end
  class DelayedCreate < Trouble; end
  def self.something
    raise Unauthorized unless authorized
    if can_create_now
      new(...)
    else
      queue_create(...)
      raise DelayedCreate
    end
  end
end

Исключения позволяют передавать дополнительные данные (например, raise Unauthorized.new "No such account" или любые пользовательские свойства, которые вы хотите добавить в свой класс), и поэтому могут быть более полезными (при необходимости).).Просто не забудьте передать семантические результаты из вашей модели в контроллер и позволить ему преобразовать их в пользовательских сообщений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...