0

我刚刚学会了如何通过tag a record查询该标签,但我不确定它是否适用于这种情况。我想在我的模型上有一列包含任意键的散列(即它们可能与每个记录不同),然后我希望能够通过这些键/值进行查询。Rails通过嵌套键/值查询

因此,像这样:

my_dog = Pet.new 
my_dog.traits = { 
    :weight => 20, 
    :has_shots => true, 
    :color => 'brown' 
} 

their_cat = Pet.new 
their_cat.traits = { 
    :weight => 4, 
    :has_shots => false, 
    :color => 'brown' 
} 

我知道我可以序列化这个数据,如果所有我想做的就是输出它以后。但是我想在这里实现的是通过散列中的键来查询这些记录的能力。例如(显然错误的查询语法):Pet.where(traits: 'weight < 25 AND color = "brown"')

这种事情可能吗?

+0

如果使用postgres和hstore列数据类型http://nandovieira.com/using-postgresql-and-hstore-with-rails。你引用的链接是使用连接表标记,为什么要使用散列?连接表有很多好处。 – Swards

+0

您可以使用Rails的内置'serialize'方法,但在这些序列化的值上创建SQL条件将非常困难。如果您使用的是PostgreSQL,请参阅HStore,如@Swards所述。如果不使用PostgreSQL,我建议你使用另一个表(类似'PetTrait',持有'pet_id','trait_name'和'trait_value')。那么在SQL – MrYoshiji

回答

0

您可以查询到根据您想要的值(:http://www.justinweiss.com/articles/should-you-use-scopes-or-class-methods/类方法对这项工作为好,但这里有对的时候喜欢一个VS其他的一些想法)上Pet定义范围。

一些例子:

scope :max_weight, -> (weight) { where("weight <= ?", weight) } 
scope :min_weight, -> (weight) { where("weight >= ?", weight) } 
scope :has_color, -> (color) { where("color = ?", color) } 

然后,假设你有机会获得你想要筛选标签的变量,你应该能够调用Pet.max_weight(25).has_color('brown')。那是你的追求?

+0

中的条件将会容易得多,谢谢!看起来每个范围都必须在课堂上定义,但是,对吗?如果有意义的话,我正在寻找的是一种过滤任意值的方法。所以如果3个'Pet'记录包含'[:traits] [:has_black_spots] = true'我希望能够过滤掉这3条记录。不是所有的'Pet'记录都会有'has_black_spots',所以我不想为它创建一个特定的范围。合理? –