use*_*136 17 search ruby-on-rails conditional-statements
我目前正在为我的rails应用程序编写一个搜索方法,目前它工作正常.我的game.rb中有以下内容:
def self.search(search)
if search
find(:all, :conditions => ['game_name LIKE ? OR genre LIKE ? OR console LIKE ?', "%#{search}%", "#{search}", "#{search}"])
else
find(:all)
end
end
Run Code Online (Sandbox Code Playgroud)
现在搜索很好,但我的问题是如果game_name中有一个记录中有'playstation'字样的记录,它将在那里完成搜索.它只返回该记录,而不是所有存储在控制台中的"playstation"的游戏.现在我明白这是因为我的条件中有'或',但我不知道另一种选择.'AND'要求所有条件匹配或根本不返回.什么是我可以使用AND和OR的替代方案?非常感谢帮助.
如果有一个解决方案有单独的搜索框和条目,那就没问题,我不一定要求搜索根据一个搜索表单找到所有搜索框.
Jef*_*eil 34
如果我正确理解你的问题,那么你的SQL对你正在尝试做的事情看起来很好.OR子句将返回column1,column2或column3中匹配的所有记录.它不会在第一场比赛中停止.我确实看到你的参数存在问题,因为第一个你正在使用LIKE和%,但在后两个你不是,也许这就是你的问题来自哪里.
这应该是你的发现(%左右第二次和第三次搜索)?
find(:all, :conditions => ['game_name LIKE ? OR genre LIKE ? OR console LIKE ?', "%#{search}%", "%#{search}%", "%#{search}%"])
Run Code Online (Sandbox Code Playgroud)
或者更好地使用DRY版本(上面不适用于Rails 4.2+):
Item.where('game_name LIKE :search OR genre LIKE :search OR console LIKE :search', search: "%#{search}%")
Run Code Online (Sandbox Code Playgroud)
sun*_*nil 20
如果您有15列要搜索,那么您将重复键15次.而不是在查询中重复键15次,你可以像这样写:
key = "%#{search}%"
@items = Item.where('game_name LIKE :search OR genre LIKE :search OR console LIKE :search', search: key).order(:name)
Run Code Online (Sandbox Code Playgroud)
它会给你相同的结果.
谢谢
我认为这是一个更清洁的解决方案.这允许您更轻松地添加/删除列.
key = "%#{search}%"
columns = %w{game_name genre console}
@items = Item.where(
columns
.map {|c| "#{c} like :search" }
.join(' OR '),
search: key
)
Run Code Online (Sandbox Code Playgroud)
在模型的所有字段中搜索的更通用的解决方案是这样的
def search_in_all_fields model, text
model.where(
model.column_names
.map {|field| "#{field} like '%#{text}%'" }
.join(" or ")
)
end
Run Code Online (Sandbox Code Playgroud)
或者更好地作为模型本身的范围
class Model < ActiveRecord::Base
scope :search_in_all_fields, ->(text){
where(
column_names
.map {|field| "#{field} like '%#{text}%'" }
.join(" or ")
)
}
end
Run Code Online (Sandbox Code Playgroud)
你只需要这样称呼它
Model.search_in_all_fields "test"
Run Code Online (Sandbox Code Playgroud)
在你开始之前..,不,sql注入在这里可能不起作用,但仍然更好更短
class Model < ActiveRecord::Base
scope :search_all_fields, ->(text){
where("#{column_names.join(' || ')} like ?", "%#{text}%")
}
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15565 次 |
最近记录: |