where(:sku =>' sku123')vs where(' sku =

时间:2016-05-11 04:32:26

标签: ruby-on-rails ruby postgresql ruby-on-rails-4 activerecord

我有一个奇怪的情况。这是我的模特:

UpcCode
  

=> UpcCode(id:integer,Upc:string,Sku:string,Active:boolean,   created_at:datetime,updated_at:datetime)

如您所见,Sku是我的专栏之一。

当我输入IRC时:

UpcCode.where(:Sku => 'SKU123').first

我得到了预期的结果:

  

UpcCode加载(0.9ms)SELECT&#34; upc_codes&#34;。* FROM&#34; upc_codes&#34;哪里   &#34; upc_codes&#34;&#34; SKU&#34; = $ 1 ORDER BY&#34; upc_codes&#34;。&#34; id&#34; ASC限制1   [[&#34; Sku&#34;,&#34; GC-115-42&#34;]] =&gt; #<UpcCode id: 95, Upc: "70163098XXXX", Sku: "SKU123", Active: true, created_at: "2016-05-11 03:12:11", updated_at: "2016-05-11 03:12:11">

但是当我使用以下语法尝试此操作时:

UpcCode.where("Sku = 'SKU123'").first

UpcCode.where('Sku = "GC-115-42"').first

我收到以下错误,好像Sku列不存在。

  

UpcCode Load(5.2ms)SELECT&#34; upc_codes&#34;。* FROM&#34; upc_codes&#34;哪里   (Sku =&#34; GC-115-42&#34;)ORDER BY&#34; upc_codes&#34;。&#34; id&#34; ASC限制1   ActiveRecord :: StatementInvalid:PG :: UndefinedColumn:ERROR:列   &#34; SKU&#34;不存在

我需要能够使用第二种语法,因为我需要操纵结果。即不区分大小写的比较。

3 个答案:

答案 0 :(得分:4)

所有非双引号的标识符都会在PG中转换为小写,因此您的列名Sku会转换为sku,因此您可以尝试这种方式来解决此问题:

UpcCode.where('"Sku" = ?','SKU123' )

答案 1 :(得分:3)

或者你可以这样做

the_sku = 'SKU123'
UpcCode.where("Sku = ?", the_sku).first

<强>更新

the_sku = 'SKU123'
UpcCode.where('"Sku" = ?', the_sku).first

PG需要您使用double-quotation标记包装区分大小写的列名。

使用?的好处是,它将您从SQL Injection

移植到

请参阅http://guides.rubyonrails.org/security.html#sql-injection

我的建议

您应遵循不区分大小写column_names的约定。 在Rails我们遵循社区惯例,原因如下

  • 它使您的代码对未来的协作者更具可预测性
  • 您可以更快速,更轻松地在社区维基中获得答案;你不必长时间怀疑
  • convention over configuration是我们Rails社区拥有的最强点。
  • ...

答案 2 :(得分:0)

尝试这样:

UpcCode.where("'upc_codes'.'Sku' = 'SKU123'").first