Search code examples
ruby-on-railsrubypg-search

Rails - pass variable to different page on redirect


appreciate if you can help. I added pg_search to my project and need to redirect user back if there is no search results at all. Here is my search controller.

/app/controllers/results_controller.rb

class ResultsController < FrontendController
  def index
    @search_results = PgSearch.multisearch(params[:query])
    if @search_results.empty?
      redirect_to :back(@search_results)
    end
  end
end

And here is my layout where i'm trying to catch search result:

/app/views/layouts/application.html.slim
...
    .search-result class="#{'visible' unless @search_results?}
      ' 0 results
...

and all I get is

/app/views/layouts/application.html.slim:165: syntax error, unexpected ')' ...isible' unless@search_results?))).to_s)); _temple_html_attri... ... ^ 
/app/views/layouts/application.html.slim:168: syntax error, unexpected keyword_do_cond, expecting ')' ...method: :get, role: 'search' do; ... ^ 
/app/views/layouts/application.html.slim:171: syntax error, unexpected keyword_end, expecting ')' ; end; @output_buffer.safe_concat(... ^ /app/views/layouts/application.html.slim:194: syntax error, unexpected keyword_ensure, expecting ')' 
/app/views/layouts/application.html.slim:196: syntax error, unexpected keyword_end, expecting ')'

I several different approaches from Stackoverflow, but nothing helped. What am I doing wrong? Rails 4.2.5.1, Ruby 2.2.3


Solution

  • Don't redirect back. Instead render a view that tells the user that there is no search results. Otherwise you get an endless loop when you hit the back button.

    class ResultsController < FrontendController
      def index
        @search_results = PgSearch.multisearch(params[:query])
      end
    end
    

    # app/views/results/index.html
    <% if @search_results.any? do %>
      <% @search_results.each do |r| %>
    
      <% end %>
    <% else %>
      No results.
      <%= render 'some_kind_of_form' %>
    <% end >
    

    Why the syntax error?

    In redirect_to :back :back is a literal symbol. You can't call literals in Ruby:

    irb(main):001:0> :foo("bar")
    SyntaxError: (irb):1: syntax error, unexpected '(', expecting end-of-input
    :foo("bar")
    

    If you want to augment the the url use url_for(:back) which is the same as request.referrer.

    # see https://ruby-doc.org/stdlib-2.1.2/libdoc/uri/rdoc/URI/HTTP.html
    uri = URI(url_for(:back))
    uri.query = { foo: 'bar' }.to_query
    redirect_to uri
    

    If you want to get the route object you can do:

    Rails.application.routes.recognize_path(url_for(:back), method: :get)