将字符串转换为符号并在if语句中使用

时间:2014-06-17 08:12:46

标签: ruby-on-rails ruby

我有一个"选项"的列表。我需要评估每个选项并将它们设置为真或假。

所以我从

开始
    if params[:account][:use_dbs].present?
      if params[:account][:use_dbs] == '1'
        @account.settings.use_dbs = true
      else 
        @account.settings.use_dbs = false
      end
    end

    if params[:account][:use_time_logs].present?
      if params[:account][:use_time_logs] == '1'
        @account.settings.use_time_logs = true
      else 
        @account.settings.use_time_logs = false
      end
    end

这实际上工作正常。但是,我最终会选择20个左右的选项而且我不想重复20次。那么我想做这样的事情......

    # handle optional screen settings
    options = ['use_dbs', 'use_time_logs']
    options.each do |option|
      if params[:account][(option.to_sym)] == '1'
        @account.settings.option.to_sym = true
      else
        @account.settings.option.to_sym = false
      end
    end

这显然会更加整洁,但我无法理解所需的语法。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

你快到了!我认为给你带来麻烦的是如何动态调用方法(即你的@account.settings.use_time_logs=调用)。您可以使用send执行此操作。请注意,您需要在属性名称的末尾添加=(当您object.attr=实际调用attr=上名为object的方法时。{ / p>

正如@Stefan指出的那样,你可以直接将布尔条件作为一个值,通过使用符号而不是字符串,你的生活也会变得更加容易(为什么一直打扰to_sym? )

所以:

# handle optional screen settings
options = [:use_dbs, :use_time_logs]
options.each do |option|
  @account.settings.send("#{option}=", params[:account][option] == '1')
end

答案 1 :(得分:0)

首先要说的是“为什么不首先使用符号?”

options = [:use_dbs, :use_time_logs]
options.each do |option|
  if params[:account][option] == '1'
    @account.settings.option = true
  else
    @account.settings.option = false
  end
end

其次,这与您的第一个不完全相同:在第一个代码中,如果params中没有该选项,则不将其设置为任何内容。在第二批代码中,您将其设置为false。我不知道这是否重要。

我认为这可以通过这样做进一步整理:

if params[:account]
  params[:account].each do |k,v|
    @account.settings.send("#{k}=", v == "1")
  end
end