我发现自己在控制器中编写了这么多代码:
params[:task][:completed_at] = Time.parse(params[:task][:completed_at]) if params[:task][:completed_at]
不要特意把我在这里做的事情挂掉,因为每次都会改变原因;但是在很多情况下我需要检查params中的值并在将其移交给create
或update_attributes
之前进行更改。
重复params[:task][:completed_at]
三次感觉非常糟糕。有更好的方法吗?
答案 0 :(得分:11)
稍微缩短这一点的一种方法是:
if c = params[:task][:completed_at]
params[:task][:completed_at] = Time.parse(c)
end
或者,你可能更喜欢这个:
params[:task][:completed_at] &&= Time.parse(params[:task][:completed_at])
在第二种情况下,只有在左侧是“真实”的情况下才会进行分配。
答案 1 :(得分:0)
我想你可以考虑做这样的事情。
在String和NilClass上实现#to_time
,可能在extensions.rb
中(如Ruby Best Practices中所推荐的那样,例如
require 'time'
class String
def to_time
Time.parse(self) # add error/exception handling to taste
end
end
class NilClass
def to_time
nil
end
end
然后你可以调用params[:task][:created_at].to_time
并且复制已经消失。
我完全不确定这必然构成“最佳做法”,但恕我直言,它符合问题的目标......
答案 2 :(得分:0)
我对Ruby并不十分熟悉,但由于它有Perl根,可能有一个允许你这样编写它的结构:
$_ = Time->parse($_) for params[:task][:completed_at] || ();
基本上利用for循环来创建变量的别名(如果存在)
可能是这样的:
(params[:task][:completed_at] || ()).each { |i| i = Time.parse(i) }
编辑:
我看到Ruby有alias
个关键字。我不熟悉它给出一个Ruby示例,但在Perl中,上面也可以编写:
local *_ = \$params[$task][$completed_at];
$_ = Time->parse($_) if defined;
指定$_
将成为$params[$task][$completed_at]
我尝试在Ruby中熟悉它,但没有找到一种方法来为一个标识符添加别名,只是全局变量。