1

我有一个像这样的商业模型和地址模型

class Business < ActiveRecord::Base
  has_one :address, as: :addressable
end

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
end

现在奇怪的部分。如果我运行以下

Business.includes(:address).where(['email like ?', '%whatever%'])

生成两个查询

SELECT `businesses`.* FROM `businesses` WHERE (email like '%whatever%')
SELECT `addresses`.* FROM `addresses` WHERE `addresses`.`addressable_type` = 'Business' AND `addresses`.`addressable_id` IN (26)

但是如果将出现在like 子句中的文本有一个点('.'),如下所示

Business.includes(:address).where(['email like ?', '%what.ever%'])

这次使用 JOIN 生成单个查询

SELECT `businesses`.`id` AS t0_r0, `businesses`.`name` AS t0_r1, `businesses`.`primary_category_id` AS t0_r2, `businesses`.`secondary_category_id` AS t0_r3, `businesses`.`sub_primary_category_id` AS t0_r4, `businesses`.`sub_secondary_category_id` AS t0_r5, `businesses`.`website` AS t0_r6, `businesses`.`phone` AS t0_r7, `businesses`.`manager_name` AS t0_r8, `businesses`.`manager_phone` AS t0_r9, `businesses`.`email` AS t0_r10, `businesses`.`created_at` AS t0_r11, `businesses`.`updated_at` AS t0_r12, `businesses`.`encrypted_password` AS t0_r13, `businesses`.`reset_password_token` AS t0_r14, `businesses`.`reset_password_sent_at` AS t0_r15, `businesses`.`remember_created_at` AS t0_r16, `businesses`.`sign_in_count` AS t0_r17, `businesses`.`current_sign_in_at` AS t0_r18, `businesses`.`last_sign_in_at` AS t0_r19, `businesses`.`current_sign_in_ip` AS t0_r20, `businesses`.`last_sign_in_ip` AS t0_r21, `businesses`.`confirmation_token` AS t0_r22, `businesses`.`confirmed_at` AS t0_r23, `businesses`.`confirmation_sent_at` AS t0_r24, `businesses`.`failed_attempts` AS t0_r25, `businesses`.`unlock_token` AS t0_r26, `businesses`.`locked_at` AS t0_r27, `addresses`.`id` AS t1_r0, `addresses`.`line1` AS t1_r1, `addresses`.`line2` AS t1_r2, `addresses`.`city` AS t1_r3, `addresses`.`country` AS t1_r4, `addresses`.`zip` AS t1_r5, `addresses`.`neighbourhood` AS t1_r6, `addresses`.`addressable_id` AS t1_r7, `addresses`.`addressable_type` AS t1_r8, `addresses`.`created_at` AS t1_r9, `addresses`.`updated_at` AS t1_r10, `addresses`.`latitude` AS t1_r11, `addresses`.`longitude` AS t1_r12, `addresses`.`gmaps` AS t1_r13 FROM `businesses` LEFT OUTER JOIN `addresses` ON `addresses`.`addressable_id` = `businesses`.`id` AND `addresses`.`addressable_type` = 'Business' WHERE (email like '%what.ever%')

我尝试为 like 子句使用不同的值,并注意到仅当输入具有点('.')并且点('.')之前至少有 2 个字符时才会生成 JOIN 查询。

几个例子

  • 'whatever' 导致 2 个没有 JOIN 的查询

  • 'w.hatever' 导致 2 个没有 JOIN 的查询

  • 'wh' 导致 2 个没有 JOIN 的查询

  • 'w.ha' 导致 2 个没有 JOIN 的查询

  • 'w。' 导致 2 个没有 JOIN 的查询

  • 'xxxxxxxxw.hatever' 导致 1 个 JOIN 查询

  • 'what.ever' 导致 1 个 JOIN 查询

  • “什么。” 结果 1 查询与加入

我的猜测是这与 Rails 认为如果 where 子句中有一个点它可能引用另一个表,所以应该应用连接,如果没有点或者之前只有一个字符点(可能是表名不能是单个字符的 y .. 猜测!!)而不是生成 2 个查询。

有人见过这种问题吗?我正在使用 Rails 3.2

4

0 回答 0