我试图从两个与搜索词中的每个词匹配的数据库表(页面和文章)中返回记录。这是我的疑问:
if params.has_key?('search_term')
words = params['search_term'].split(' ')
query = "
select
p.id
, p.title
, p.slug
, p.created_at
, p.content
, 'page' as type
from pages p
where 1 = 1
"
words.each do |word|
query << " and p.title like '%" << word << "%' or p.content like '%" << word << "%'"
end
query << "
union all
select
a.id
, a.title
, a.slug
, a.created_at
, a.content
, 'article' as type
from articles a
where 1 = 1
"
words.each do |word|
query << " and a.title like '%" << word << "%' or a.content like '%" << word << "%'"
end
@search_results = ActiveRecord::Base.connection.execute(query)
end
首先,如何清除循环中word
的值以防止SQL注入攻击?我想知道是否有必要进一步清理word
,因为我已经拆分了搜索字词串。
其次,是否有更好的方法来接近我尝试做的事情?我对Ruby / Rails比较陌生,所以欢迎指点。
提前感谢您的帮助。
答案 0 :(得分:1)
您应该尽可能使用内置的查询工具。因此,假设您有Page类和Article类,则可以使用select和where
matched_pages = Page.select(:title, :slug, :created_at, :content)
matched_articles = Articles.select(:title, :slug, :created_at, :content)
words.each do |word|
matched_pages = matched_pages.where(["title LIKE :word OR content LIKE :word", {word: "%#{word}%"}])
matched_articles = matched_articles.where(["title LIKE :word OR content LIKE :word", {word: "%#{word}%"}])
end
如果你需要将它们合并在一起,你可以将两个结果连接起来像
@search_results = matched_pages + matched_articles
然后,如果你想在视图中:
<% @search_results.each do |item| %>
<tr>
<td><%= item.title %></td>
<td><%= item.slug %></td>
<td><%= item.created_at %></td>
<td><%= item.content %></td>
<td><%= item.class.name.downcase %></td>
</tr>
<% end %>
当然,您可能还想做很多其他事情,并且除了示例之外,还有其他(通常更好的)方式在视图中显示数据,但这可以帮助您了解数据的外观等。