如何根据搜索关键字 rails 从 2 个表中获取数据
Posted
技术标签:
【中文标题】如何根据搜索关键字 rails 从 2 个表中获取数据【英文标题】:How to get data from 2 tables based on search keyword rails 【发布时间】:2017-01-09 11:11:07 【问题描述】:我有 2 个表 schools
和 private_schools
,它们彼此不相关。我需要做的是从两个表中搜索数据以填充结果。
两个表都有属性name
,我需要从中获取结果。因此,当用户编写一些关键字时,将从两个表中搜索数据。
这是我正在尝试的查询,但它返回错误。
查询:
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
【问题讨论】:
贴出这三个模型的代码 @ShamsulHaque 添加了模型代码。 你想从两张表中得到什么?数据输出是否相似?如果没有,您将需要两个单独的查询。否则,你可以一个。将结果映射到两个数组并加入它们。所以你将有一个结果数组,而不是一个集合。湾。运行原始 sql 查询 我想根据输入的搜索短语从两个表中获取学校名称。如何以相同的方法管理 2 个查询?你们这些cmets是对的,而且是有道理的。 :) 否则之后的东西就是我要找的东西。所以运行 2 个查询并将它们作为 1 个结果集加入。我该怎么做? 【参考方案1】:错误原因以下查询需要两个参数,每个参数一个 ?
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])
还有什么期待吗?
我认识用户。那种东西也是没用的,也不需要,但是我们应该如何处理这个问题以同时从两个表中搜索关键字?
实际上,您的User.
查询将返回用户列表,而不是学校或私立学校的列表,因此,如果您不期望用户列表,您可能正在寻找其他东西......也许是学校列表?
如果您的 schools
和 private_schools
具有相同的结构,您应该查看 inheritance 并为两个模型使用相同的表。
现在你可以这样做:
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
【讨论】:
我发现User.
不是必需的,因为我只想从两个表中查询结果而不包含User
的东西。 User
不需要,因为我在上面发布了相同的内容。如果没有User
因素,我们能做到吗?
如果表不相关,您将不得不执行两个单独的查询...User.
将返回这些条件下的用户列表,而不是学校或私立学校的列表,所以不确定是什么你在找吗
是的,我想单独查询,我们可以用同样的方法管理吗?你的 cmets 现在对我来说很有意义。对不起,请。【参考方案2】:
我有几件事要给你:
includes
用于指定要包含在结果集中的关系。所以schools
和private_schools
之间没有任何关系。所以直截了当你不能像这样查询它,因为你不能join
两个没有任何关系的表。您可以对school
和private_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
,当您尝试使用example
名称获取posts
时,它不会触发任何额外的查询,因为它已经加载了该数据。因此,这仅在模型之间存在关系时才有效。
school
和private_school
可以是一个单独的模型,如果它们的属性相同的话。你可以添加一个属性is_private
,它是布尔值,如果是私立学校,它的值是true
。 (这取决于你的属性)
【讨论】:
我想选择选项 1。是否有任何示例如何以一种查找搜索关键字的方法运行这两个查询?谢谢 因此您将在一种方法中为其编写两个查询,并且可以将它们添加到一个数组中。我已经更新了答案。【参考方案3】:如果您要在应用程序中频繁执行诸如此类的“复杂”查询,我强烈建议您查看“ransack” gem。它使这样的查询变得轻而易举,并且您的代码库变得干净。
MyModel.search(:private_school_name_or_school_name_cont => params[:q).result
参考:https://github.com/activerecord-hackery/ransack
【讨论】:
以上是关于如何根据搜索关键字 rails 从 2 个表中获取数据的主要内容,如果未能解决你的问题,请参考以下文章
在 Rails 中将 2 个表导出为 CSV [如何选择特定列?]