Rails,如何查询数据库中的关联条目
Rails, how to query database for associated entries
我正在为一个小型档案创建一个查询界面,我需要了解如何在数据库中查询相关条目,例如关键字、作者等。
我有一个资源模型,每个条目都有一系列列以及一系列关联,例如作者、关键字等。
class Resource < ApplicationRecord
# Associations
belongs_to :bibliographic_level
belongs_to :editor
belongs_to :fund
belongs_to :land
belongs_to :parent, class_name: "Resource"
belongs_to :resource_collocation
belongs_to :resource_type
has_many :resource_authors, dependent: :destroy
has_many :authors, through: :resource_authors
has_many :items, class_name: "Resource", foreign_key: "parent_id"
has_many :resource_keywords, dependent: :destroy
has_many :keywords, through: :resource_keywords
...
在我的控制器中,我为数据库查询定义了一个操作
def opac
@resources = Resource.page(params[:page]).order('id ASC').per_page(10).search(params)
end
在我的模型中,我根据用户选择任何标题、作者或关键字作为他的搜索掩码这一事实创建了不同的搜索查询。
def self.restricted_search(params)
if params[:searchAny].present?
all.where(['title LIKE ? OR description LIKE ?', "%#{params[:searchAny]}%", "%#{params[:searchAny]}%"])
elsif params[:searchTitle].present?
where('title LIKE ?', "%#{params[:searchTitle]}%")
...
end
如何查询数据库并显示作者姓名的一部分包含“Mich”或关联特定关键字“X”的所有资源?
我想是这样的
elsif params[:searchAuthor].present?
joins(:resource_authors).where('resource_authors.authors_name = ?', "%#{params[:searchAuthor]}%")
elsif params[:searchKeyword].present?
joins(:resource_keywords).where('resource_keywords.keyword_word = ?', "%#{params[:searchKeyword]}%")
end
我不清楚语法,因为在这两种情况下,一个资源都可以有多个作者,我将不得不请求一个作者包含特定字符串的所有资源。
我怎样才能让它工作?
提前致谢。
加法
查询作者时,我在日志中得到以下输出:
Resource Load (1.7ms) SELECT `resources`.* FROM `resources` INNER JOIN `resource_authors` ON `resource_authors`.`resource_id` = `resources`.`id` INNER JOIN `authors` ON `authors`.`id` = `resource_authors`.`author_id` INNER JOIN `resource_authors` `resource_authors_authors_join` ON `resource_authors_authors_join`.`author_id` = `authors`.`id` INNER JOIN `resources` `resources_authors` ON `resources_authors`.`id` = `resource_authors_authors_join`.`resource_id` WHERE (resource_type_id != '7') AND (resource_authors_resources_join.author_name = '%test%') ORDER BY id ASC LIMIT 10 OFFSET 0
和此错误消息:
ActionView::Template::Error (Mysql2::Error: Column 'resource_type_id' in where clause is ambiguous):
99: <%= will_paginate @restricted_resources, previous_label: h("<"), next_label: h(">"), class: "pagination" %>
查询关键字时,我得到:
Resource Load (1.7ms) SELECT `resources`.* FROM `resources` INNER JOIN `resource_keywords` ON `resource_keywords`.`resource_id` = `resources`.`id` WHERE (resource_type_id != '7') AND (resource_keywords.keyword_word = '%test%') ORDER BY id ASC LIMIT 10 OFFSET 0
和错误信息:
ActionView::Template::Error (Mysql2::Error: Unknown column 'resource_keywords.keyword_word' in 'where clause'):
99: <%= will_paginate @restricted_resources, previous_label: h("<"), next_label: h(">"), class: "pagination" %>
您需要定位正确的 table 并使用 LIKE
而不是 =
。
elsif params[:searchAuthor].present?
joins(:authors)
.where('authors.authors_name LIKE ?', "%#{params[:searchAuthor]}%")
elsif params[:searchKeyword].present?
joins(:keywords)
.where('keywords.keyword_word LIKE ?', "%#{params[:searchKeyword]}%")
end
我正在为一个小型档案创建一个查询界面,我需要了解如何在数据库中查询相关条目,例如关键字、作者等。
我有一个资源模型,每个条目都有一系列列以及一系列关联,例如作者、关键字等。
class Resource < ApplicationRecord
# Associations
belongs_to :bibliographic_level
belongs_to :editor
belongs_to :fund
belongs_to :land
belongs_to :parent, class_name: "Resource"
belongs_to :resource_collocation
belongs_to :resource_type
has_many :resource_authors, dependent: :destroy
has_many :authors, through: :resource_authors
has_many :items, class_name: "Resource", foreign_key: "parent_id"
has_many :resource_keywords, dependent: :destroy
has_many :keywords, through: :resource_keywords
...
在我的控制器中,我为数据库查询定义了一个操作
def opac
@resources = Resource.page(params[:page]).order('id ASC').per_page(10).search(params)
end
在我的模型中,我根据用户选择任何标题、作者或关键字作为他的搜索掩码这一事实创建了不同的搜索查询。
def self.restricted_search(params)
if params[:searchAny].present?
all.where(['title LIKE ? OR description LIKE ?', "%#{params[:searchAny]}%", "%#{params[:searchAny]}%"])
elsif params[:searchTitle].present?
where('title LIKE ?', "%#{params[:searchTitle]}%")
...
end
如何查询数据库并显示作者姓名的一部分包含“Mich”或关联特定关键字“X”的所有资源?
我想是这样的
elsif params[:searchAuthor].present?
joins(:resource_authors).where('resource_authors.authors_name = ?', "%#{params[:searchAuthor]}%")
elsif params[:searchKeyword].present?
joins(:resource_keywords).where('resource_keywords.keyword_word = ?', "%#{params[:searchKeyword]}%")
end
我不清楚语法,因为在这两种情况下,一个资源都可以有多个作者,我将不得不请求一个作者包含特定字符串的所有资源。
我怎样才能让它工作?
提前致谢。
加法
查询作者时,我在日志中得到以下输出:
Resource Load (1.7ms) SELECT `resources`.* FROM `resources` INNER JOIN `resource_authors` ON `resource_authors`.`resource_id` = `resources`.`id` INNER JOIN `authors` ON `authors`.`id` = `resource_authors`.`author_id` INNER JOIN `resource_authors` `resource_authors_authors_join` ON `resource_authors_authors_join`.`author_id` = `authors`.`id` INNER JOIN `resources` `resources_authors` ON `resources_authors`.`id` = `resource_authors_authors_join`.`resource_id` WHERE (resource_type_id != '7') AND (resource_authors_resources_join.author_name = '%test%') ORDER BY id ASC LIMIT 10 OFFSET 0
和此错误消息:
ActionView::Template::Error (Mysql2::Error: Column 'resource_type_id' in where clause is ambiguous):
99: <%= will_paginate @restricted_resources, previous_label: h("<"), next_label: h(">"), class: "pagination" %>
查询关键字时,我得到:
Resource Load (1.7ms) SELECT `resources`.* FROM `resources` INNER JOIN `resource_keywords` ON `resource_keywords`.`resource_id` = `resources`.`id` WHERE (resource_type_id != '7') AND (resource_keywords.keyword_word = '%test%') ORDER BY id ASC LIMIT 10 OFFSET 0
和错误信息:
ActionView::Template::Error (Mysql2::Error: Unknown column 'resource_keywords.keyword_word' in 'where clause'):
99: <%= will_paginate @restricted_resources, previous_label: h("<"), next_label: h(">"), class: "pagination" %>
您需要定位正确的 table 并使用 LIKE
而不是 =
。
elsif params[:searchAuthor].present?
joins(:authors)
.where('authors.authors_name LIKE ?', "%#{params[:searchAuthor]}%")
elsif params[:searchKeyword].present?
joins(:keywords)
.where('keywords.keyword_word LIKE ?', "%#{params[:searchKeyword]}%")
end