如何在Rails 5中使用text_field发送搜索查询(URL参数)?

时间:2018-11-08 08:35:05

标签: ruby-on-rails ruby-on-rails-4 ruby-on-rails-5

在任务控制器(动作索引)中,我有这行:

@tasks = Task.where("title LIKE '%#{params[:q]}%'")

在视图中,我有这样的form_tag:

= form_tag tasks_path(format: :js), method: :get do |f|
  = text_field_tag :q, params[:q]
  = submit_tag :Search

它工作正常,在终端中输出:

Started GET "/tasks.js?utf8=%E2%9C%93&q=example&commit=Search" for 127.0.0.1 at 2018-11-08 10:28:37 +0200
Processing by TasksController#index as JS
  Parameters: {"utf8"=>"✓", "q"=>"example", "commit"=>"Search"}
  Rendering welcome/index.html.haml
  Task Load (0.4ms)  SELECT "tasks".* FROM "tasks" WHERE (title LIKE '%example%')

但是我需要使用form_for而不是form_tag。 我的form_for表单:

= form_for tasks_path, method: :get, remote: true do |f|
  = f.text_field :q, value: params[:q]
  = f.submit :Search

端子输出:

Started GET "/index?utf8=%E2%9C%93&%2Ftasks%5Bq%5D=fdvdfvdfv&commit=Search" for 127.0.0.1 at 2018-11-08 10:30:11 +0200
Processing by WelcomeController#index as JS
  Parameters: {"utf8"=>"✓", "/tasks"=>{"q"=>"fdvdfvdfv"}, "commit"=>"Search"}
  Rendering welcome/index.html.haml within layouts/application
  Task Load (0.4ms)  SELECT "tasks".* FROM "tasks" WHERE (title LIKE '%%')

这是行不通的,在'%%'之间为空。 也许你可以帮我。

2 个答案:

答案 0 :(得分:1)

您应该使用form_tag而不是form_forform_for用于为模型对象创建表单,情况并非如此。

为回答您的问题,当您查看日志中生成的params时,您拥有"/tasks"=>{"q"=>"fdvdfvdfv"}。因此params[:q]在这种情况下不起作用。

我的最终答案是form_tag

答案 1 :(得分:0)

在Rails 5.1+中,您应该使用form_with来代替form_forform_tag

没有模型

= form_with(url: tasks_path(format: :js), method: :get) do |f|
  = f.text_field :q, params[:q]
  = f.submit_tag :Search

确保对SQL查询进行参数设置,以避免出现SQL注入漏洞:

@tasks = Task.where("title LIKE ?", "%#{params[:q]}%")

虚拟模型

或者您可以创建一个虚拟模型,该模型是没有数据库表的模型:

# app/models/seach_query.rb
class SearchQuery
  include ActiveModel::Model
  attr_accessor :q
end

= form_with(model: (@search_query || SearchQuery.new) url: tasks_path(format: :js), method: :get) do |f|
  = f.text_field :q
  = f.submit :Search

class TasksController < ApplicationController
  # ...
  def index
    @tasks = Task.all
    if params[:search_query]
      @search_query = SearchQuery.new(params.fetch(:search_query).permit(:q))
      @tasks = @tasks.where('tasks.title LIKE ?', "%#{ @search_query.q }%")
    end
  end
end

虚拟模型的优点是您可以使用验证,使用I18n模块本地化字段等并组织代码。