Posts tagged "search"

Rails is very friendly whenever you need to create forms to input data to your web app’s database. Things get a little different when you must have forms and you don’t want to save anything in the database. For that, you have to resort to other ways, maybe creating tableless models.

However, there are some simple cases that even creating a new class seems an overkill, such as forms for searching or filtering data in your app. In these cases, you just want a form that user can pick options and hit a button to see the results. When returning to the user, it is expected to have that form filled with the options the user had chosen before, but there is no simple, clean way to do that with plain old “form_tag”. Here is where our little tip comes in.

OpenStruct is a cool lib that comes with the Ruby Standard Library. “It is like a hash with a different way to access the data” says the documentation:

>> user = OpenStruct.new({:name => 'John', :last_name => 'Doe'})
=> #<OpenStruct name="John", last_name="Doe">
>> user.name
=> "John"
>> user.last_name
=> "Doe"
>> user.bla
=> nil

We can use it to fool our old friend “form_for” helper to think we’re dealing with normal AR objects, so we can create a method that wraps “form_for”, simple as this:

require 'ostruct'
module SearchFormHelper
  def search_form_for(object_name, options={}, &block)
    options[:html] = {:method => :get}.update(options[:html] || {})
    object = OpenStruct.new(params[object_name])
    form_for(object_name, object, options, &block)
  end
end

Inside the view, you will do the same way you do with AR models:

<% search_form_for :search do |f| %>
  <p>
    <%= f.label :start_at %>
    <%= f.date_select :start_at %>
  </p>
  <p>
    <%= f.label :end_at %>
    <%= f.date_select :end_at %>
  </p>
  <p>
    <%= f.submit 'Search' %>
  </p>
<% end %>

That’s pretty much it! If you’re filtering data, by a category for example, try checking the has_scope plugin, works like a charm in combination with this tip, but it is a matter for other post.

And you, reader, do you have any little tricks like this? If you don’t mind, share with us!