R形搜索多态的域名

时间:2018-04-09 18:00:46

标签: ruby-on-rails

在我的模型患者身上,它通过多态关联发挥作用,称为角色。该角色有一个belongs_to:user。我需要在该用户模型上使用last_name进行搜索...

class Patient < ApplicationRecord
    has_one :role, :as => :roleable, dependent: :destroy
    accepts_nested_attributes_for :role
end

class Role < ApplicationRecord
    belongs_to :user
    accepts_nested_attributes_for :user

    belongs_to :roleable, polymorphic: true, optional: true
end

如何构建该查询以便我可以使用User的名字进行搜索?这就是我迄今为止在我的患者模型中所拥有的:

def self.search(query)
    items = Patient.joins(role: :user).where('first_name LIKE :search OR last_name LIKE :search', search: query)
end

我的主要困惑在于.joins部分以及如何让用户参与其中。

2 个答案:

答案 0 :(得分:3)

在查询这样的连接表时,需要将表名添加到属于连接表的列中:

def self.search(query)
  Patient.joins(role: :user).
      where('users.first_name LIKE :search OR users.last_name LIKE :search', search: query)
end

答案 1 :(得分:3)

您在正确的轨道上,但您需要指定要将WHERE条件应用于哪个表:

def self.search(query)
  Patient.joins(role: :user)
         .where('users.first_name LIKE :q OR users.last_name LIKE :q', q: "%#{query}%")
end

创建局部变量并显式返回它也是完全多余的,因为Ruby隐式返回最后一个值。

请注意,LIKE区分大小写。如果您使用的是Postgres,则可能需要使用ILIKE来执行不区分大小写的搜索。在其他DB上将值转换为小写:

def self.search(query)
  Patient.joins(role: :user)
         .where('LOWER("users.first_name") LIKE :q OR LOWER("users.last_name") LIKE :q', q: "%#{query.downcase}%")
end