I have a simple search form in my Rails 3 app:
<%= form_tag search_path, :method => "get" do %>
<%=开发者_如何学Go text_field_tag :q, params[:q] %>
<%= submit_tag "search", :name => nil %>
<% end %>
When the user hits the submit button, they get taken to the URL: http://myapp.com/search?utf8=%E2%9C%93&q=foobar
(where %E2%9C%93
gets displayed as a checkmark: ✓).
I'm not doing anything with the utf8
parameter, so I want to keep the URL clean by removing it entirely. That is, I want users to get taken to the URL: http://myapp.com/search?q=foobar instead.
How do I do this?
form_tag
in Rails 4.2 (and probably earlier) has a :enforce_utf8
option;
If set to false, a hidden input with name utf8 is not output.
(Same as https://stackoverflow.com/a/28201543/430695)
Once you understand the purpose of the Rails UTF-8 param, and for some reason you still need to remove it, the solution is easier than you think...just don't use the form_tag
helper:
<form action="<%= search_path %>" method="get">
<%= text_field_tag :q, params[:q] %>
<%= submit_tag "search", :name => nil %>
</form>
Even though you aren't doing anything with the parameter, Rails is. It's to correct some issues in IE's parameter encoding. Yehuda has more info here:
What is the _snowman param in Ruby on Rails 3 forms for?
There is gem (utf8_enforcer_workaround) for applying the utf8 param only for non standards complying browsers (or any other logic for that sake). This is handy if you don't want to bother your well behaving users with IE workarounds.
I made an initializer to remove the param from GET requests. It's obviously a hack.
This goes in config/initializers/overrides.rb
:
# Don't let Rails add a utf8=✓ param to GET forms.
# See http://stackoverflow.com/questions/3222013/what-is-the-snowman-param-in-rails-3-forms-for for details.
module ActionView::Helpers::FormTagHelper
private
def extra_tags_for_form_with_utf8_param_excluded_from_gets(html_options)
old = extra_tags_for_form_without_utf8_param_excluded_from_gets(html_options)
non_get = old.include?('"_method"') || old.include?('"'+request_forgery_protection_token.to_s+'"')
if non_get
old
else
old.sub(/<[^>]+name="utf8"[^>]+"✓"[^>]*>/, '').html_safe
end
end
alias_method_chain :extra_tags_for_form, :utf8_param_excluded_from_gets
end
Ideally, Rails should probably have a setting for this, or at least rewrite extra_tags_for_form so it's less messy to patch.
Try this in your ApplicationController:
def default_url_options(options={})
options.delete('utf8')
end
Using before_action and redirecting to another action worked for me. For example, if you are searching for posts, set up a route for search on collection.
resources :posts do
collection do
get 'search'
end
end
and make HTTP GET request for posts#index action.
<%= form_tag posts_path, method: :get do %>
<%= search_field_tag :q, params[:q], placeholder: "Search posts" %>
<%= submit_tag "Go" %>
<% end %>
and then in PostsController,
before_action :check_for_query, only: :index
...
private
def check_for_query
redirect_to articles_search_url(q: params[:q]) if params[:q].present?
end
and call Post.search in posts#search action and render index page.
def search
Post.search(params[:q])
render :index
end
The URL will look like /posts/search?q=foo
I think we should use: enforce_utf8: false
in form_tag.
Ex:
= form_tag search_path, method: :get, id: 'searchForm', enforce_utf8: false
精彩评论