Forum: Ruby on Rails Params Merge and URL sorting/pagination

Posted by Alpha Blue (elricstorm)
on 2009-07-02 21:48
Hi all,

Here's my general setup on the specific template I'm having issues with:

will_paginate for pagination
custom methods for sorting
1-form for team search
1-form for search by date

When searching for a team for instance, the url returned will be:

/rushing_offenses?search=Florida

When searching by date, the url returned will be:

/rushing_offenses?compiled_on=2009-07-02

Pagination has a show all button:

/rushing_offenses?numteams=120&orderby=rank&sortby=asc

Pagination has a show simple button:

/rushing_offenses?orderby=rank&sortby=asc

If I click on each page number within will paginate the URL changes to:

/rushing_offenses?compiled_on=2009-07-02&orderby=rank&page=2&sortby=asc

My table helper functions for sorting and for the show all / show simple
are:

# adds up / down images for asc and desc sorting to all table columns
based on controller name called
  def sort_column(title, direction)
    direction == "asc" ? image = "up.gif" : image = "down.gif"
    (link_to image_tag(image, :border=>0, :alt => direction),
:controller => controller.controller_name, :numteams => (@showall ? 120
: nil), :orderby => title, :sortby => direction) if !@searchteams
  end

# adds a button to show all teams on tables based on controller name
called.
  def show_all_teams
    (link_to "Show All Teams", :controller =>
controller.controller_name, :numteams => 120, :orderby => 'rank',
:sortby => 'asc') if !@showall
  end

# adds a button to show simplified views on tables based on controller
ame called..
  def show_simple_view
    (link_to "Show Simple View", :controller =>
controller.controller_name, :numteams => nil, :orderby => 'rank',
:sortby => 'asc') if @showall || @searchteams
  end

The main call to the list function in my index is done through the
following controller call:

list(params[:search], params[:page], params[:orderby], params[:sortby],
params[:numteams], params[:compiled_on])

Which is sent to the model:

  def self.list(search, page, orderby, sortby, numteams, datevar)
    # convert datevar to today's date if it's empty/nil/or not formatted
properly due to form_tag lacking model validation checks
    datevar = todaysdate if datevar.empty? || datevar.nil? ||
DATE_VALIDATE_REG.match(datevar).nil?
    # we need to convert datevar to time and find the beginning of that
week for scope comparison
    convert_time = datevar.to_time.beginning_of_week
    # we need to reconvert the time back to a readable week start date
    week_start_date = convert_time.to_date.strftime('%Y-%m-%d')
    # using our named scope to checked for compiled_on which is a date
type column to search within specified date ranges
    named_scope :compiled_on_week, lambda { { :conditions =>
['compiled_on >= ? and compiled_on <= ?', week_start_date, datevar] } }
    # automatically ordering by rank if our orderby is nil or empty
    orderby = "rank" if orderby.nil? || orderby.empty?
    # deciding whether to sort by ascending or descending
    orderall = (sortby != 'asc' && sortby != nil) ? "DESC" : "ASC"
    # calling our named_scope along with will_paginate to pull our data
    compiled_on_week.paginate :joins => :team, :conditions => ['name
like ?', "%#{search}%"], :order => orderby + " #{orderall}", :per_page
=> numteams, :page => page
  end

=======================================================

Okay, sorry for the long setup before getting to my question(s).  I just
wanted to be certain that I provided as much information as I could
about the issue.

What I want is to have all the params merged into one long URL to look
like so:

/rushing_offenses?search=Florida&?compiled_on=2009-07-02&?numteams=120&orderby=rank&page=2&sortby=asc

I know that I need to use params.merge for this but I'm not sure how to
go about doing it with the different parts on my page as well as with
some of the helper models I defined above.

What advice/suggestions can you give me?

Many great thanks in advance!
Posted by Alpha Blue (elricstorm)
on 2009-07-03 15:37
Looking back at this, I probably asked way too much with this scenario..

So, in case someone reads this I think what I'm looking for is a fairly 
simple params.merge tutorial or explanation of the mechanics when using 
it.

Thanks..
Posted by Alpha Blue (elricstorm)
on 2009-07-03 21:17
Okay I figured 80% of this out on my own after some trial and testing. 
I still need help with params.merge on the forms only.  Here's what I 
did for the rest:

  def sort_column(title, direction)
    direction == "asc" ? image = "up.gif" : image = "down.gif"
    (link_to image_tag(image, :border=>0, :alt => direction), 
params.merge(:controller => controller.controller_name, :numteams => 
(@showall ? 120 : nil), :orderby => title, :sortby => direction))
  end
  # adds a button to show all teams on tables based on controller name 
called.
  def show_all_teams
    (link_to "Show All Teams", params.merge(:controller => 
controller.controller_name, :numteams => 120, :orderby => 'rank', 
:sortby => 'asc', :page => 1, :search => nil)) if !@showall
  end
  # adds a button to show simplified views on tables based on controller 
ame called..
  def show_simple_view
    (link_to "Show Simple View", params.merge(:controller => 
controller.controller_name, :numteams => nil, :orderby => 'rank', 
:sortby => 'asc')) if @showall || @searchteams
  end

I added params.merge to the link tos and it just merged the params with 
the existing ones with no changes.  I had to modify the Show All Teams 
link to show :page => 1 since it would get stuck if it was on simple 
view and a page requester was say on 3..  I also had to change the 
:search => nil so that show all would clear any search results and show 
all teams.

This entire fix worked for 80% of the content.

Now, I still have issues with my forms.  Here are the views:

      <td align="left" valign="middle">
        <% form_tag controller.controller_path, :method => 'get' do %>
          <%= hinted_text_field_tag :search, params[:search], "Enter 
Team" %>
          <%= submit_tag "Team Search", :name => nil %>
        <% end %>
      </td>
      <td align="left" valign="middle">
        <% form_tag controller.controller_path, :method => 'get' do %>
          <%= calendariffic_input(true, :compiled_on, 
'calendariffic/date.png', 'search_cal', '%Y-%m-%d', 
params[:compiled_on], {}, {:class => 'borderless'}) %>
          <%= submit_tag "Date Search", :name => nil %>
        <% end %>
      </td>

How do I use params merge with the forms?

Many thanks in advance.
Posted by Alpha Blue (elricstorm)
on 2009-07-04 03:07
Still can't get it to work.  I've tried this on my search form:

        <% form_tag(params.merge(:page => 1, :numteams => 20), :method 
=> 'get') do %>
          <%= hinted_text_field_tag :search, params[:search], "Enter 
Team" %>
          <%= submit_tag "Team Search", :name => nil %>
        <% end %>

but if I click search, it removes all other params from the URL and goes 
back to ?search=team

Still not sure what to do with form_tags and params.merge.  I have it 
working for everything but forms..

Anyone?
Posted by Alpha Blue (elricstorm)
on 2009-07-05 16:54
I took a break from this issue and tried to get back to it again today. 
I even tried implementing hidden fields but that doesn't work as 
expected.  Can anyone offer input into this issue?  Advice? 
Suggestions?

1.  What options do I have for building a form using form_tag with 
params.merge?

I have looked through a lot of sites online and

<% form_tag(params.merge(:compiled_on => params[:compiled_on]), :method 
=> 'get') do %>
  <%= hinted_text_field_tag :search, params[:search], "Enter Team" %>
  <%= submit_tag "Team Search", :name => nil %>
<% end %>

.. should work..

However, it does not.  I still only get search="Florida" and I don't get 
search="florida"&compiled_on="2009-07-02"..

I hate bumping my own thread but either this is a very easy issue or 
it's a very complicated issue and no one has any advice for me.  I've 
worked through this issue as far as I can by myself.  I need some 
assistance.

Thanks.
Posted by Alpha Blue (elricstorm)
on 2009-07-05 16:57
I just wanted to add one more thing here:

<%= debug params %> shows:

--- !map:HashWithIndifferentAccess
search: florida
compiled_on: "2009-07-05"
action: index
controller: rushing_offenses

and the URL shows:

http://localhost:3000/rushing_offenses?search=florida

It should show:

http://localhost:3000/rushing_offenses?search=florida&compiled_on=2009-07-05

.. using what was listed in the post before this one.

Please assist.
Posted by Frederick Cheung (Guest)
on 2009-07-05 17:32
(Received via mailing list)
On Jul 5, 10:54 am, "Älphä Blüë" <rails-mailing-l...@andreas-s.net>
wrote:
> <% form_tag(params.merge(:compiled_on => params[:compiled_on]), :method
> => 'get') do %>
>   <%= hinted_text_field_tag :search, params[:search], "Enter Team" %>
>   <%= submit_tag "Team Search", :name => nil %>
> <% end %>
>
> .. should work..
>
> However, it does not.  I still only get search="Florida" and I don't get
> search="florida"&compiled_on="2009-07-02"..
>

If a form's submission method is get, then when you submit the form
its input elements are serialized and turned into a query string. The
standard just say that a ? and this query string is appended to the
action attribute (which would probably create an invalid url such as
foo?bar=baz?search=Florida ). In practise most browsers seem to just
ignore the query string that was part of the action attribute,
although I can't see anything in the standards that says this is ok
(equally I can't see anything that says that the query strings need to
be concatenated in a smart way). Given that the browser is going to
junk the query string bit from the form's action attribute you'll need
all of your various parameters as form parameters (unless you have
routes which push those parameters into the path of the url)..

Fred
Posted by Alpha Blue (elricstorm)
on 2009-07-05 19:00
> If a form's submission method is get, then when you submit the form
> its input elements are serialized and turned into a query string. The
> standard just say that a ? and this query string is appended to the
> action attribute (which would probably create an invalid url such as
> foo?bar=baz?search=Florida ). In practise most browsers seem to just
> ignore the query string that was part of the action attribute,
> although I can't see anything in the standards that says this is ok
> (equally I can't see anything that says that the query strings need to
> be concatenated in a smart way). Given that the browser is going to
> junk the query string bit from the form's action attribute you'll need
> all of your various parameters as form parameters (unless you have
> routes which push those parameters into the path of the url)..
> 
> Fred

Thanks Fred,

So, realistically if I just want a one-form submit query, I have to 
either add hidden field inputs that pull the given parameters on the 
given page so the form builds the query, or I have to use routes to do 
something similar...

I'm almost inclined to believe that it will be simpler to just create an 
advanced search form with all queries in place..
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.