【问题标题】:How can I send a search query(URL params) using text_field in Rails 5?如何在 Rails 5 中使用 text_field 发送搜索查询(URL 参数)?
【发布时间】:2018-11-08 08:35:04
【问题描述】:

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

@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 '%%')

而且它不起作用,'%%' 之间为空。 也许你能帮帮我。

【问题讨论】:

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


    【解决方案1】:

    您应该使用form_tag 而不是form_for。 form_for 用于为模型对象创建表单,这不是您的情况。

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

    我的最终答案是form_tag。

    【讨论】:

    【解决方案2】:

    在 Rails 5.1+ 中,您应该使用 form_with 替换 form_for 和 form_tag。

    没有模型

    = form_with(url: tasks_path(format: :js), method: :get) do |f|
      = f.text_field :q, value: params[:q]
      = f.submit :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 模块等本地化字段并组织您的代码。

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 2013-12-14
      • 1970-01-01
      • 2016-06-30
      • 2012-06-06
      • 1970-01-01
      相关资源
      最近更新 更多