I have this form:
<%= form_tag posts_path, :method => :get, :class => "search_nav" do %>
<%= text_field_tag :search, params[:search], :class => "input-long search-query", :placeholder => "#{t('.search_nav')}" %>
<%= hidden_field_tag('ip', "#{request.ip}") %>
<%= hidden_field_tag('city', "#{request.location.city}") %>
<%= hidden_field_tag('country', "#{request.location.country}") %>
<%= content_tag(:div, "",:class => "icon-search") %>
<% end %>
I get a url something like:
http://localhost:3000/en/posts?utf8=%E2%9C%93&search=check+params&ip=127.0.0.1&city=&country=Reserved
My question is:
Can I hide or encrypt the url params ip, city and country?
I can not use POST because I have paginate results:
<a rel="2" href="/en/posts?city=&country=Reserved&ip=127.0.0.1&page=2&search=check+params&utf8=%E2%9C%93">2</a>
<a rel="3" href="/en/posts?city=&country=Reserved&ip=127.0.0.1&page=3&search=check+params&utf8=%E2%9C%93">3/a>
Encrypting URL parameters is pretty pointless. Why don't you want the user to see these values? Sure you COULD encrypt them before adding them to the form, but is that really necessary?
Furthermore, and perhaps more importantly, if these values are based on the request, then there is a good chance you don't need to submit them in the first place. #{request.xxx} is going to be the same on the result page as is on the form page. Is there any good reason to pass these along? By submitting these as GET parameters, you're actually sending redundant information to the server. Ruby/Rails is already going to calculate these values based off of the IP address automatically when the next page is loaded.
The problem here isn't with the form, but rather with the logic you've applied to designing it. I think you may have over-analysed your situation, and need to take a step back and re-think the problem.
Related
I have the following form
<%= form_for :key, url: unblock_keys_path, :html => {:method => :get} do |f| %>
<%= f.text_field :value %>
<%= button_to "Unblock", method: :get %>
<% end %>
Which works fine when I enter key values in the text box. But i want the user to be able to access the endpoint directly from the url as well.
Right now the params this request generates are:
{"utf8"=>"✓", "key"=>{"value"=>"x0vdPYWb9nAfyNjFS-UAGQ"},
"authenticity_token"=>"+Oi45DHYpPAiNbKrw5kNjWMVrQgCyLsBkhVb7huB0dr+xm/oKXxzTShajVUYEWxl9qlFLfjWsP4C4JM30DTGoA==",
"controller"=>"keys", "action"=>"unblock"}
url: http://localhost:3000/keys/unblock?utf8=✓&key%5Bvalue%5D=x0vdPYWb9nAfyNjFS-UAGQ&authenticity_token=%2BOi45DHYpPAiNbKrw5kNjWMVrQgCyLsBkhVb7huB0dr%2Bxm%2FoKXxzTShajVUYEWxl9qlFLfjWsP4C4JM30DTGoA%3D%3D
I want to be able to access localhost:3000/keys/unblock?<key_value>
What changes do I need to make in my request and routes?
This localhost:3000/keys/unblock?<key_value> is not a valid url*. The ? denotes the start of the params, and then everything after that needs to have the form "name=value", joined with "&".
Do you mean localhost:3000/keys/unblock/<key_value>?
If so then add a route like
get '/keys/unblock/:value', to: 'keys#unblock'
This will send eg /keys/unblock/foo to your unblock action, with params[:value] = "foo"
*note - technically it's not illegal, but it's poorly formed and almost certainly not what you want to do.
In my Rails app I have a simple form that filters all the user's invoices by date:
<%= form_tag invoices_path, :method => 'get' do %>
<%= text_field_tag :date, params[:date] %>
<%= submit_tag "Search" %>
<% end %>
When a user enters a date in his preferred date format, e.g. 27/07/2014, I want this to be shown in the URL as /invoices?date=2014-07-14 because this can be handled much more easily by the database and also looks better than /invoices?date=25%2F07%2F2014.
Is there any way to convert a GET parameter like this in Rails?
Thanks for any help.
First of all, the date prettifying is to be done on the client side, since you want the pretty value to be shown in the query params already.
The form_tag may be supplied with onsubmit callback:
<%= form_tag invoices_path,
:method => 'get'
:onsubmit => 'return validate(this)' do %>
Here validate() would be a javascript validation method that would return true or false; you are free to prettify and overwrite the date value there.
Probably there is a more elegant way to accomplish that, but the aforementioned one worked well for me. Hope it helps.
The following works great for carrying forward data from one page to another:
<%= link_to 'New Work Order', new_workorder_path, :class => 'btn btn-primary', :onclick => session[:worequest_id] %>
How would I add a 2nd field? The following doesn't work:
<%= link_to 'New Work Order', new_workorder_path, :class => 'btn btn-primary', :onclick => session[:worequest_id] = #worequest.id, [:client_id] = #worequest.client_id %>
Thanks!
UPDATED
This is the code I'm using in the new work order form. It picks up the worequest_id field from the session
<% if session[:worequest_id] != nil %>
<%= f.hidden_field :worequest_id, :value => session[:worequest_id] %>
onclick doesn't really work this way – it's an html attribute used to store JavaScript code to be executed when the element is clicked. While you can use it to evaluate Ruby code in the context of a Ruby method call (in this case as part of the options hash given to link_to), it doesn't really make sense to do so.
In your first example, it doesn't actually do anything. If you check your rendered html on the page where that link appears, I expect it evaluates to something like New Work Order. You can, however, store data in session (which is persistent for as long as the user remains logged in), which is why you're seeing this data carrying forward from page to page.
If you're trying to fill in default values for the new workorder, you could pass them as params to the path method:
link_to 'New Work Order',
new_workorder_path('workorder[worequest_id]' => #worequest.id,
'workorder[client_id]' => #worequest.client_id),
:class => 'btn btn-primary'
In your workorders#new action, your model instantiation would need to include the params:
def new
#workorder = Workorder.new(params[:workorder])
end
However, this might not be the best way to proceed. If there will always be a client or worequest associated with a workorder, you might want to look into nested routes.
I have a single text box form on my home page (/).
Right now the way my Rails routes is set up, when I submit this form, it takes me to /search, but it doesn't publish the query string in my url.
In other words, when I enter in "hello" in that form and press submit, I want to end up at "/search?query=hello". I know that "hello" is in params[:query], but how do I get Rails to publish that query string in the landing page URL after I submit the query?
I read the Rails routes guide but that talks about incoming query strings in the URL, not Rails publishing the URL with the query string visible.
Thanks.
My form tag so far:
<% form_tag(:controller => "search", :action => "search", :method => :get) do %>
<%= text_field_tag 'query' %>
<%= submit_tag "Search"%>
<% end %>
If I do this, I get /search?method=get, but what I would like to see is /search?query=foo.
You just need define a form with get method instead of post
<% form_tag search_url, :method => :get do %>
<%=text_field_tag :search %>
<%= submit_tag %>
<% end %>
Make sure that your form's method (as shown in the HTML page that a client would see before submitting the form) is GET not POST. With POST, the params[:query] is hidden from the user (this is often used for login forms, forms that would submit credit cards or other sensitive information). But if you want the query to show in the URL, you need to use the GET method. Rails itself isn't responsible for this behavior, it's all on the web browser's side.
In the application there is a default report the user see's listing all the calls for a certain phone. However, the user can select a date range to sort the list from. Doing that, everything works correctly, but when the user selects the date range and changes to the second page, the date-range is lost and it goes back to the default view for the second page.
In my controller, I'm checking to see if the date_range param is being passed in. If it isn't, I display the entire listing, if it is, I display the records in between the certain date range.
The problem is, when I click on a new page, the new parameter doesn't include the old date-range that it should.
How do I go about doing this, I was thinking of doing some class level variable test but that isn't working out the way I thought. And I'm pretty stuck.
I don't have the code right in front of me, but if I remember correctly it's something like this:
<% form for :date_range do |f| %>
<%= f.calendar_date_select :start %>
<%= f.calendar_date_select :end %>
<%= f.Submit %>
<% end %>
And in the controller, it's something like:
if params[:date_range] == nil
find the complete listings without a date range
else
find the listings that are within the date range
end
The main problem is that you're using a POST request when submitting the form, but will-paginate uses a GET request. You should also use form_tag instead of form_for because form_for will nest the fields in a hash which is not possible with GET.
<% form_tag items_path, :method => 'get' do %>
<%= calendar_date_select_tag :start_date %>
<%= calendar_date_select_tag :end_date %>
<%= submit_tag "Submit", :name => nil %>
<% end %>
Then check params[:start_date] and params[:end_date] directly. You'll need to change items_path to whatever page you want the form to go to.
This is untested but it should get you in the right direction.
You could modify the link_to (assuming that's how you go through pages) so that it passed the date_range param.
= link_to 'Next', #whatever_path, :date_range => #date_range
where #date_range could be set in your controller by capturing your params in an instance variable.. .
But there may be a better solution.