我正在运行一个Sinatra应用程序,其中包含一些额外的类,用于创建用户和其他一些用户(没有数据库,它从Web服务提供)。我正在尝试从我的用户模型中发送一个闪存通知(使用https://github.com/nakajima/rack-flash),但无法弄清楚如何访问flash方法/变量,因为我已超出范围。
类似的东西:
class User def something if true flash[:notice] = 'Good job' else # nope end end end
通过简单的require 'models/user'
答案 0 :(得分:2)
这是一个XY问题[1]。 Sinatra负责发送Flash消息,而不是您的User对象,因此设置Flash的代码应该在Sinatra应用程序中,而不是在User类中。
答案 1 :(得分:1)
您不应要求您的用户(型号)与UI(视图)对话。这很糟糕/不是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"
或您要添加到类中的任何自定义属性),因此可能更有用(适当时)。只需记住将模型中的语义结果传递给控制器,然后将其转换为面向用户的消息。