4

我发现自己经常在控制器中编写这段代码:

params[:task][:completed_at] = Time.parse(params[:task][:completed_at]) if params[:task][:completed_at]

不要挂断我在这里的具体工作,因为原因每次都在变化;但是在很多情况下,我需要检查 params 中的值并在将其交给createor之前对其进行更改update_attributes

重复params[:task][:completed_at]三遍感觉很糟糕。有一个更好的方法吗?

4

3 回答 3

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])

在第二种情况下,仅当左侧是“真实的”时才会发生分配。

于 2010-01-14T23:04:32.237 回答
0

我想你可以考虑做这样的事情。

#to_time在 String 和 NilClass 上实现,可能在一个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,重复就消失了。

我完全不确定这是否一定构成“最佳实践”,但恕我直言,它符合问题的目标......

于 2010-01-15T00:16:11.560 回答
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 中简单地使用它,但没有看到别名的方法,只是全局变量。

于 2010-01-15T18:35:50.760 回答