Search code examples
ruby-on-railssearchtagging

Rails: Searchform for Tags


I build a simple tagging system into my webapp (I've followed these steps: http://www.sitepoint.com/tagging-scratch-rails/)

So, now it's working fine that people can click on a Tag e.g. Dogs and they are going to "app.com/search/dogs".

But, now the people should also search for tags by using a form input field. At the moment I've tried this:

<%= form_tag('search', method: 'get', controller: 'static', action: 'home') do %>
  <%= text_field_tag :tag, params[:tag], placeholder: "Search Posts" %>
  <%= submit_tag("Search") %>
<% end %>

That brings the user to: "app.com/search/?utf8=✓&tag=Dogs&commit=Search" and that's not working. Is there a way to achieve the other logic?

Here some (maybe) interesting code samples:

routes.rb

# search by tags
get 'search/:tag', to: 'static#home', as: "search"

post.rb

def self.tagged_with(name)
Tag.find_by_name!(name).posts
end

static_controller.rb

def home
  if params[:tag]
    @posts = Post.tagged_with(params[:tag])
  else
    @posts = Post.all
  end
end

posts_helper.rb

def tag_links(tags)
  tags.split(",").map{|tag| link_to tag.strip, search_path(tag.strip) }.join(" ")
end

Sorry, I'm a real beginner :) Thank you in advance!


Solution

  • Let me start with a note. The form_tag does not take controller or action parameters. Right now, they are just being printed as a form HTML tag attributes.

    <%= form_tag('search', method: 'get', controller: 'static', action: 'home') do %>
    
    # Generates
    <form controller="static" action="search" accept-charset="UTF-8" method="get">
    

    You probably meant to do:

    <%= form_tag('search', method: 'get') do %>
    

    Now, to back to your question. Basically, you want to dynamically set the action attribute of your form. This is only possible if you use some javascript.

    Add a class to your search form tag:

    <%= form_tag('search', method: 'get', class: 'tag-search-form') do %>
    

    Add this javascript code to your page:

    $(document).ready(function(){
      $('.tag-search-form').submit(function(e){
        var new_action_url = $(this).attr('action') + "/" + $('#tag', this).val();
        $(this).attr('action', new_action_url)
      });
    });
    

    This will send user to search/{tag-field-value} URL. But, it would add all the parameters to it as well (search/test?utf8=✓&tag=test&commit=Search). If you don't want them, then you'd have to remove them in javascript before sending or alternatively setting your form's method attribute to POST.