Search code examples
ruby-on-railsruby-on-rails-5rails-activerecordransack

Run method in Controller on another page before showing results with Ransack


My question

With Ransack, when submit is clicked, is there a way to call a method before displaying the results on another page.

Summary

I have a page called manualPull that contains a single search_field:

<%= search_form_for @q do |f| %>
      <div class="field">
        <%= f.label :Username_cont, "Lookup"  %>
        <%= f.search_field :Username_cont %>
      </div>

      <div class="actions"><%= f.submit "Pull & Search"%></div>

<% end %>

Basically what I want to happen is when a user clicks on the submit button, we will send a call to the controller of another page (sessions_controller#manuallookupsession) to pull data from our database then show the results on that other page.

What I tried

I tried adding url: 'sessions_controller#manuallookupsession' to search_form_for :

<%= search_form_for @q do |f|, url: 'sessions_controller#search' %>
         <div class="field">
           <%= f.label :Username_cont, "Lookup"  %>
           <%= f.search_field :Username_cont %>
         </div>
   
         <div class="actions"><%= f.submit "Pull & Search"%></div>
   
<% end %>

I also added the following line to the sessions_controller before_action :index, only: [:search]

That almost worked in the sense that it would show the search results in the new page but it would not run the manuallookupsession method in the sessions_controller. The other weird behavior is that the manuallookupsession method would run every time I refresh the manualPull page but not when I clicked submit.

Update1:

session_controller

Here is the code for my session_controller:

class PppoeSessionsController < ApplicationController
  before_action :index, only: [:search]
  def index
    @q = Session.ransack(params[:q])
    @session = @q.result.order(:username).page params[:page]
    @sessions_to_export = @q.result.order(:username).all
    respond_to do |format|
      format.html
      format.csv { render text: @sessions_to_export.to_csv }
      format.xlsx
    end
  end
 end
 def search
    puts("TEST")
    @username = params[ 'username' ]
    @sessionsearch = Session.new
    @sessiondetails = Session.new
    if @username
      @sessiondetails = @sessionsearch.pull_user(@username)
      respond_with(@pppoe_session)
    end
 end

Solution

  • Here is what worked for me finally: In my search_form_for I added a hidden field called search as follows:

      <%= search_form_for @q, url: 'sessions_controller' do |f| %>
        <div class="field">
          <%= f.label :username_eq, "Lookup"  %>
          <%= f.search_field :username_eq %>
          <%= hidden_field_tag "search", true %>
        </div>
    
        <div class="actions"><%= f.submit "Refresh & Search" %></div>
    
      <% end %>
    

    And in my sessions_controller I added the following check to my index class:

    if params[:search] == "true" && params[:commit] == "Refresh & Search"
          search #This is a call to a method
    end
    

    Furthermore in my search class I was able to retrieve the entered username from the URL (since it was a get request and not a post request) with the following code (you need to require 'cgi' at the start of the class):

          url = request.original_fullpath.split("/").last
          parameter_hash = CGI.parse(URI.parse(url).query)
          @username = parameter_hash["q[username_eq]"][0].to_s
    

    Thanks to @morissetcl for leading me to the correct answer in the comments of your last answer.

    I wish there was a way to give you credits for it.