简体   繁体   中英

PostgreSQL Full Text search does not take params from form in Rails

I'm trying to replicate railscasts #343 in my rails app with this code:

class Article < ActiveRecord::Base
  def self.text_search(query)
    if query.present?
      where("description @@ :q", q: query)    
    else
      where(nil)
    end
  end

class ArticlesController < ApplicationController
  def index
    @articles = Article.text_search(params[:query])
  end

and this view form:

<%= simple_form_for articles_path, method: :get do |f| %>
  <%= f.input :query, autofocus: true, label: false %>
  <%= f.submit 'Search', name: nil %>
<% end %>

In console text_search method works. From log: Parameters: {"utf8"=>"✓", "/en/articles"=>{"query"=>"word"}, "locale"=>"en"} I see that params are sent but I still get all articles listed and no search is performed: Article Load (0.5ms) SELECT "articles".* FROM "articles"

I have rails 4.2.2, PostgreSQL 9.3.7, ruby 2.2.5

You need to pass the search params as:

Article.text_search(params[:search]["query"]) 

And add @article to the simpleform_for line:

<%= simple_form_for @article, articles_path, method: :get do |f| %>

And add @article = Article.new to your new action in the controller.

Your attribute will then be nested inside :article! You can see it in the console output that the parameters sent by the articles form will always be wrapped in the class name the form is for (Article) via Rails Form helpers.

Update:

Because the simple_form_for wasn't passed @article specifically, it will be wrapped in the name of the submit action which in this case is search. Leaving you with: params[:search]["query"]

A more Rails approach would be to include @article thus wrapping your parameter hash as described above ( params[:article][:query] ):

<%= simple_form_for @article, {url here}, {options like 'method: :get' or 'remote: true' here } do |f| %>

For extra info. since everyone loves extra info, Rails provides a way to specify the wrapper name for your params hash in the form_for call thus you can also do something like:

<%= simple_form_for (@article, as: :search), articles_path, method: :get do |f| %>

This would be best practice if you really want to keep the params wrapped in 'search' IMO because you're specifying the class object in the form call and letting yourself know what it's doing with that object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM