我试图将我的所有逻辑都排除在视图之外,并提出了下面的代码,尽管我已经知道它不会返回实际的分数值,它只会返回,如果它是一个胜利,丢失或领带
def find_result(schedule)
return "not required" if schedule.event != '1' or schedule.time >= Time.now
if schedule.for.nil? or schedule.against.nil?
"Not Entered"
else
tie = '<b>T</b> '
tie << schedule.for.to_i
tie << ' - '
tie << schedule.against.to_i
win = '<b>W</b> '
win << schedule.for.to_i
win << ' - '
win << schedule.against.to_i
return raw tie if schedule.for.to_i == schedule.against.to_i
schedule.for.to_i > schedule.against.to_i ? (raw win) : "Lost"
end
端
答案 0 :(得分:2)
不要将<<
与整数一起使用。见文档:
http://www.ruby-doc.org/core-1.9.3/String.html#method-i-3C-3C
它可能会将您的输入/输出数字转换为未在HTML中显示的字符。
在附加数字时,请使用格式化工具或其他内容,或者仅to_s
而不是to_i
。
使用字符串格式的示例(未经测试):
def find_result(schedule)
return "not required" if schedule.event != '1' or schedule.time >= Time.now
if schedule.for.nil? or schedule.against.nil?
"Not Entered"
elsif schedule.for.to_i < schedule.against.to_i
"Lost"
else
raw "<b>%s</b> %d - %d" % [
schedule.for.to_i == schedule.against.to_i ? 'T' : 'W',
schedule.against.to_i,
schedule.for.to_i
]
end
将逻辑排除在视图之外是好的,但它更合适 将部分内容移至模型中,即时间表的结果(未输入, 赢,输,领带)
在这个例子中,我将创建一个简单的内部类,它封装了那个逻辑 附表利用了解自己的结果。你可以通过多种方式做到这一点 虽然(例如模块与类或直接在Schedule上的方法)
然后,我将演示如何使用提供的逻辑在助手中使用新的计划,或者只是查询结果本身并将其用作翻译查找的关键字(I18n)。
注意这是未经测试的并且有点伪代码(我没有特别使用任何I18n库,只是猜测方法和翻译格式)。但它应该适用于一些调整,或者至少让你知道另一种做事方式。
class Schedule
# The schedule jus instantiates a result object when you ask for one.
# For convenience the result's to_s is it's value, e.g. "win"
def result
Result.new(self.for, self.against)
end
# delegate methods querying the result
delegate :win?, :loss?, :tie?, :not_entered?, :to => :result
class Result
Values = %(win loss tie not_entered)
Win = Values[0]
Loss = Values[1]
Tie = Values[2]
NotEntered = Values[3]
attr_reader :for, :against
def initialize(_for, against)
@for = _for
@against = against
end
def value
return NotEntered unless [@for, @against].all?
case v = @for - @against
when v.zero? then Tie
when v > 0 then Win
else Loss
end
end
alias :to_s :value
def not_entered?; self.value == NotEntered end
def win?; self.value == Win end
def loss?; self.value == Loss end
def tie?; self.value == Tie end
end
end
# then in your helper, something like
def find_result(schedule)
# you'd want to refactor this requirement part too
return "not required" if schedule.event != '1' or schedule.time >= Time.now
# Now you could do it essentially the way you had, with ifs or a
# case statement or what have you, but the logic for the result is kept
# where it belongs, on the class.
if schedule.not_entered?
"Not Entered"
elsif schedule.loss?
"Loss"
else
prefix = schedule.win? ? "W" : "T"
raw "<b>%s</b> %d - %d" % [prefix, schedule.for, schedule.against]
end
# OR you could use some kind of translation library using the `value`
# returned by the result. Something like:
key = ["schedule", schedule.outcome.value].join(".")
raw I18n.translate(key, {:for => schedule.for, :against => schedule.against})
end
# if you used the latter, it would lookup the translation in some other place,
# e.g. some config JSON, which might look like this (more or less, and
# depending on the lib you use):
{
"schedule": {
"win": "<b>W</b> {{for}} - {{against}}",
"tie": "<b>T</b> {{for}} - {{against}}",
"loss": "Loss",
"not_entered": "Not Entered"
}
}
# The translation has a few advantages. It would allow you to sub in other
# languages, but also, it conveniently keeps all of the app's text in one
# place, if you stick to using it.