使用轨道进行高级搜索 - 活动记录 SQl 查询的问题



我在我的rails应用程序之上构建了一个搜索功能,我可以根据用户的姓名和性别进行搜索和过滤。搜索工作正常,唯一的问题是它不能准确工作!

例如,如果我搜索男性用户,搜索结果也会得到女性用户。我认为这是因为我正在使用 ActiveRecord 查询,我将用户表的性别列与插入的参数进行比较,因为"女性"和"男性"是两个非常相似的词,它得到的结果与两个属性相关。这是我使用的ActiveRecord查询,并且正在工作(虽然不准确(:

"gender LIKE ? ", "%#{params[:gender]}%"

所以我使用了不同的 ActiveRecord 查询:

"gender: %#{params[:gender]}%"

不幸的是,第二个查询破坏了一切。我在终端中收到此错误:

SQLite3::SQLException: unrecognized token: ":": SELECT "users".* FROM "users" WHERE (gender: %Male%))

这些 ActiveRecord 查询应该属于我的"搜索"模型的searches_controller。这是我的控制器:

def index
if params[:username] || params[:gender].present?
@search = User.where('true').paginate(page: params[:page], per_page: 10)
@search = User.where("name LIKE ? ", "%#{params[:username]}%") unless params[:username].blank?
@search = User.where("gender LIKE ? ", "%#{params[:gender]}%") unless params[:gender].blank?
else
@search = User.all.paginate(page: params[:page], per_page: 10)
end
end
def create
@search = Search.create(username: params[:username], gender: params[:gender])
redirect to @search
end
private
def search_params
params.require(:search).permit(:users, :gender)
end

这是我的搜索模型的索引,我在其中迭代正在搜索的内容(@search(并显示在搜索结果中:

<h1> Your Search Results </h1>
<% if @search.nil? %>
<p> No Results Found </p>

<% else %>
<ul class="users">
<% @search.each do |user| %>
<%= user.name %>
<%= user.gender %>
<% end %>
</ul>
<% end %>
<p><%= link_to 'All Users',  users_path %></p>

这是一个小视频,我可以在其中解释我想做什么:https://drive.google.com/file/d/1G5FYytvmdI6iKjmwlH16NeftGwsEnLQU/view?usp=sharing

两个问题: 1(完全匹配您可以做的参数

@search = User.where(gender: params[:gender]) unless params[:gender].blank?

剩下的就是底层的LIKE克劳萨,如果你想用LIKE来做,这是正确的语法

@search = User.where("gender LIKE ? ", "#{params[:gender]}") unless params[:gender].blank?

2( 您正在覆盖 @search 变量,因此如果您同时拥有这两个参数,则您的 name 参数查询永远不会保留。最后试试这个

@search = User.all
@search = @search.where("name LIKE ? ", "%#{params[:username]}%") unless params[:username].blank?    
@search = @search.where("gender LIKE ? ", "%#{params[:gender]}%") unless params[:gender].blank?

使用LIKE ?会使你的代码容易受到 SQL 注入的影响,所以我绝对建议你改变你的方法。

我想你会使用类似的东西来解决问题

User.where("name = ? AND gender = ?", params[:username], params[:gender])

此外,每次使用查询时,请以活动记录查询指南作为参考。你会在那里找到很多有用的东西。

最新更新