Как я могу отправить поисковый запрос (параметры URL), используя text_field в Rails 5? - PullRequest
0 голосов
/ 08 ноября 2018

В контроллере задач (индекс действия) у меня есть эта строка:

@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 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 голосов
/ 08 ноября 2018

В Rails 5.1+ вы должны использовать form_with, который заменяет form_for и form_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 и т. Д. И систематизировать свой код.

0 голосов
/ 08 ноября 2018

Вы должны использовать form_tag, а не form_for. form_for используется для создания формы для объекта модели, а это не ваш случай.

И чтобы ответить на ваш вопрос, когда вы смотрите на сгенерированный params в журнале, у вас есть "/tasks"=>{"q"=>"fdvdfvdfv"}. поэтому params[:q] не будет работать в этом случае.

Мой окончательный ответ, иди с form_tag.

...