我有一个"选项"的列表。我需要评估每个选项并将它们设置为真或假。
所以我从
开始 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
这显然会更加整洁,但我无法理解所需的语法。有人可以帮忙吗?
答案 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