如何根据搜索关键字从 2 个表中获取数据 rails

How to get data from 2 tables based on search keyword rails

我有 2 个表 schoolsprivate_schools,它们彼此不相关。我需要做的是从两个表中搜索数据以填充结果。

两个表都具有我需要从中获取结果的属性 name。因此,当用户输入一些关键字时,将从两个表中搜索数据。

这是我正在尝试的查询,但它 returns 错误。

查询:

User.includes(:schools, :private_schools).where("schools.name = ? or 
private_schools.name = ?", params[:keyword])

我知道 User. 之类的东西也没有用,也不需要但是我们应该如何解决这个问题以同时从两个表中搜索关键字?

错误是:

ActiveRecord::PreparedStatementInvalid(错误数量的绑定变量(1 对 2)在:schools.name = ? 或 private_schools.name = ?):

根据评论,模型代码为:

私立学校:

class PrivateSchool < ActiveRecord::Base
  belongs_to :teacher
  has_many :private_school_specializations, :dependent => :destroy
  has_many :private_classes
  has_many :invitation_promo_codes
  has_many :popular_schools, as: :resource, :dependent => :destroy
end

学校:

class School < ActiveRecord::Base
  belongs_to :user
  has_many :students
  has_many :subjects
  has_many :teachers
  has_many :departments
  has_many :student_ids
  has_many :teacher_ids
  has_many :class_rooms
  has_many :popular_schools, as: :resource, :dependent => :destroy
end

用户:

class User < ActiveRecord::Base
  has_one :school
  has_one :student
  has_one :teacher
  accepts_nested_attributes_for :student
  accepts_nested_attributes_for :teacher
end

我有几样东西要给你:

  1. includes用于指定要包含在结果集中的关系。所以你在 schoolsprivate_schools 之间没有任何关系。所以直截了当你不能像这样查询它,因为你不能 join 两个 table 没有任何关系。您可以为每个 table schoolprivate_school.

    做一个单独的查询
    schools = School.where(name: params[:name])
    schools << PrivateSchool.where(name: params[:name])
    schools.flatten!
    

您可以像这样将两者放入一个数组中,然后在视图上循环。要仅取出您可以添加的名称:

   pluck(:name)

包括是不同的东西。例如:

User.includes(:posts).where('posts.name = ?', 'example')

Post 属于 User 时,include 将加载 posts,当您尝试获取 posts 使用 example 名称,它不会触发任何额外的查询,因为它已经加载了该数据。所以这只有在模型之间存在关系时才有效。

  1. 如果schoolprivate_school的属性相同,则可以是一个模型。您可以只添加一个 is_private 的属性,它是布尔值,如果是私立学校,它的值将是 true。 (这取决于你的属性)

ERROR REASON 以下查询需要两个参数,每个参数一个 ?

User.includes(:schools, :private_schools).where("schools.name = ? or 
private_schools.name = ?", params[:keyword])

所以

User.includes(:schools, :private_schools).where("schools.name = ? or 
private_schools.name = ?", params[:keyword], params[:keyword])

或者只是

User.includes(:schools, :private_schools).where("schools.name = :name or 
private_schools.name = :name", name: params[:keyword])

还有其他期待吗?

I know the User. sort of thing is also useless and is also not needed but how we should cope this issue to search keywords from both tables at same time?

实际上您的 User. 查询将 return 用户列表而不是学校列表或 private_schools,因此如果您不希望看到用户列表,您可能正在查找其他……也许是学校列表?

如果您的 schoolsprivate_schools 具有相同的结构,您应该查看 inheritance 并为两个模型使用相同的 table。 现在你可以这样做:

def my_result
  schools = School.where(name: params[:name]).to_a
  private_schools = PrivateSchool.where(name: params[:name]).to_a
  schools + private_schools # combine both arrays
end

如果您打算在您的应用程序中经常执行 "complex" 此类查询,我强烈建议您查看 "ransack" gem。它使这样的查询变得轻而易举,并且您的代码库很干净。

MyModel.search(:private_school_name_or_school_name_cont => params[:q).result

参考:https://github.com/activerecord-hackery/ransack