Search code examples
ruby-on-railsajaxkaminariransack

Passing filter and page params to AJAX actions in Rails


I've been wondering on how to resolve that problem - but so far it has just left me with a smoking head.

I'm using ransack and kaminari in combination with ajax create, update and delete modals. There is only an index page with a large, paginated list of entries (in my case questions).

Now if there is no filter and no pagination applied all works fine. But when, for example, I switch to page two and edit an entry the list of questions is refreshed with the first page content. The same of course happens on any filtered result or a combination of both.

Here's part of the source:

Code used in before_action on index, create, update, destroy actions in QuestionsController:

def find_questions
  @q = Question(params[:q])

  @questions = @q.result(distinct: true).order('created_at DESC').page(params[:p])
end

_save.js.erb partial which is rendered by create, update and destroy actions:

$("#index").html("<%= escape_javascript(render partial: 'questions_index') %>")

The questions_index partial:

-if @questions.empty?
    ...
-else
    -@questions.each do |q|
        [...]
        =link_to t('ui_commands.show'), question_path(q)
        =link_to t('ui_commands.edit'), edit_question_path(q), remote: true
        =link_to t('ui_commands.delete'), delete_question_path(q), remote: true
        [...]           

The filtering and pagination itself are not "ajaxified" - they are are represented in the params.

I know the solution to my problem but a can't get around solving it:-(

I know I have to somehow pass the params (in my case "p" and "q") to the create, update and destroy actions. But can I do that?

I hope that was enough elaborate for anyone to offer me help. It's greatly appreciated.


Edit: Code used in _form partial

=form_for @question, remote: true do |f|
    [...]
    =f.submit class: 'btn btn-primary'
    [...]

Solution

  • You should be able to pass the current params into the path helper:

    =link_to t('ui_commands.show'), question_path(q, params)

    This will add the current query string params to the end of the path.

    If you need to call the path helper with a hash, for example:

    question_path(id: 6)
    

    you can merge the params in. This also allows you to transform the querystring parameters if you need to.

    question_path(params.merge({ id: 6 }))
    
    question_path(params.merge({ id: 6, p: params[:p] + 1 }))
    
    question_path(q, params.merge({ p: params[:p] - 1 }))
    

    Edit:

    Responding to your edit regarding passing parameters through a form_for using a resource, try adding hidden fields to the form:

    =hidden_field_tag :p, params[:p]
    =hidden_field_tag :q, params[:q]
    

    http://apidock.com/rails/v3.2.13/ActionView/Helpers/FormTagHelper/hidden_field_tag