示例模型用户:
create_table "users"
t.string "name"
t.boolean "admin"
t.boolean "internal"
end
。在编写查询时,不知道将使用哪个布尔值,因此变量(例如usertype
)用于存储字符串“admin”或“internal”。它基本上意味着我想在where子句中使用引用属性。
执行以下查询:
User.select("id").where("#{usertype} = 't'")
在我的开发sqlite数据库中工作正常(因为sqlite将true存储为't',false存储为'f'),但我想在另一个数据库(例如Mysql或Postrgres)上使用相同的查询可能不起作用。
或者我试过
User.select("id").where("#{usertype} = ?", true)
它也有效,不使用特定于sqlite的't'。但是,这是一个很好的,独立于数据库的解决方案吗?
答案 0 :(得分:1)
您应该始终使用true
或false
(或将评估'truthy'或'falsy`的变量或代码)并让rails处理转换,但DBMS会存储布尔值。
您可以在第二个示例中执行此操作
User.select("id").where("#{usertype} = ?", true)
所以,答案是“是的,这是一个很好的,独立于数据库的解决方案”。但是,你可以让它更整洁:如果所有条件都是“=”变种,那么你可以使用哈希,比如
{:foo => "bar"}
{"foo" => "bar"}
都等同于
["foo = ?", "bar"]
这意味着在您的情况下,您可以省去字符串评估,只需将变量传入。
User.select("id").where({usertype => true})
或者,如果您想跳过可选的{
& }
User.select("id").where(usertype => true)
编辑:回复关于在ruby代码中使用动态定义的方法的评论,以从对象中获取值。
您可以使用send
方法调用对象上的相应访问者。例如,
@foo.bar == 123
相当于
@foo.send("bar") == 123
所以,在你的例子中你会说
a.send(usertype)
作为旁注,如果你想设置 usertype的值(我认为你的情况下没有意义,只是一个例子),你需要调用方法的“setter”版本,可以是admin=
或internal=
。因此,在这种情况下,您 需要使用字符串评估:
@user.send("#{usertype}=", "foo")
就像说
@user.admin = "foo"
或
@user.internal = "foo"