Ruby on rails parameters are appearing in the url - ruby-on-rails

Hi im having two actions check and display in my controller and i have two views check.html.erb and display.html.erb in the view corresponding to those actions. The check method has a form in it's view
Here is the check.html.erb
<%= form_for :display_command_list, :method => "get", :url => {:action => "display"} do |f| %>
<%= f.label :username %>
<%= f.text_field :username %><br />
<%= f.label :password %>
<%= f.password_field (:password) %><br />
<%= f.submit "Submit"%>
<% end%>
Below are both the actions:
def check
end
def display
#some code here
respond_to do |format|
format.html
end
end
When i fill the form in check view, it submits the form the display action and display action redirects to display view. But the problem is /display.html.erb is having all the parameters submitted in the form in it's url like this - /display?%username%=myname... I think my check method needs something to be written in it so that the form is submitted to display method and the url does not contain the parameters in the form.
I cannot use the parameters in the check method using params as they are empty and it throws a nil object error
Please help
Update:
I used a :method => post instead of a :method=> get in the form_for tag after seeing
how can I hide params I transmit to a method (like form_for seems to do)?
and it does not show any parameters in url.
But now when i go to another view from display.html.erb (say do_something.html.erb) and click on back button to come back to my display.html.erb, it says the web page expired.
Please let me know if iam not clear in asking the question or if iam doing something obviously wrong here..

Why don't you like having parameters in url? That's standard practice. Anyway you should either use POST and face some issues with browser behavior (like returning back to the page as you described or Ctrl-R-ing the page) or use GET and have all parameters in the url. That's how HTTP works.

Related

Rails Search form - Pass parameter from view to controller

I have the following in my view:
<%= form_for :search do |f| %>
<%= f.label :search %>
<%= f.text_field :search %>
<%= f.submit 'Search' %>
<% end %>
I am attempting to create a post action from the f.submit button which will route to a specific controller action. I then need that action to redirect back to my initial view, but pass in the text_field parameter on the redirect. How can I access the text_field parameter in my view as well as pass it through a redirect?
The easiest way to do it is from this question: Passing parameters in rails redirect_to
redirect_to search_path({ :search => params[:search] })
your parameters will come in a normal hash, and you can access them via params[:search][:search] in your controller.
generally just look into the rails server log, you can see the data your browser sends to rails right there

edit form submitting to the wrong url and remote: true failing to be picked-up

This has been driving me nuts because it doesnt seem to make any sense.
I want to do something relatively simple.
Display an edit form in a modal on the index page.
I have the following code looping through a collection of sites
<%= render(#sites) %>
<%= will_paginate #sites %>
Within the sites partial i have the following form hidden away
<%= simple_form_for site, remote: true do |f| %>
<%= f.input :name %>
<%= f.input :matter %>
<%= f.submit "Save", :class => "button gr thirt", id: "site_save" %>
<% end %>
instead of generating the expected HTML i get the following, linking to the show action, am I missing something fundamental here?
<form accept-charset="UTF-8" action="/sites/1" class="simple_form edit_site" data-remote="true" method="post" novalidate="novalidate">
</form>
I was looping through a collection of #sites, a results returned by a call to Site.all
so the object being served to the above form is one of the |site|'s contained within #sites
If you serve a form_for form with a an object retrieved from the database or a 'new record' object like Site.new, it will automatically differentiate and modify the route etc accordingly between the create and the update action.
The site object contained in the #sites block was not recognizable by the form_for. So a quick re factor to request an edit from via ajax, and provide the form with the instance variable created by the edit action (#site = Site.find(params[:id]) ) was recognizable by the form_for helper and meant that the submit action, accordingly adjusted to the correct route.

Rails: Two Different Submit buttons in a form

I'm trying to create a simple form with two different submit buttons: one which will do a normal submit, and one which will do an ajax submit and render a partial. But I'm not sure how to do this because both go towards the same create action. I tried something like this:
/views/layouts/_form.html.erb:
<div id="theform">
<%= form_for(#user, :remote => true, :form_to_validate => 'user') do |f| %>
Name: <div id='name'><%= f.text_field :name %></div><br/>
Email: <div id='email'><%= f.text_field :email %></div><br/>
Phone Number: <div id='phone_number'><%= f.text_field :phone_number%></div><br/>
<%= f.submit "Normal Submit", name:'normal' %>
<%= f.submit "Ajax Submit" %>
<% end %>
</div>
app/controllers/user_controller.rb:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if params[:normal]
render :partial => "layouts/user"
end
end
EDIT: this may seem like an odd task but it was an assignment given to me to demonstrate I could do it both ways. I know how to do the AJAX submit and the normal submit separately but my confusion is with having two submits in the form! :)
Why not write some JS that listens to the click or submit and you route it in JS if its ajax $.ajax to the ajax location else let it go through normally if its not and dont stop the propagation.
I don't think you need two submit buttons. Have the ajax button simply call the $.ajax method and send your data.
Alternately, you could have the ajax button call $('#formid').submit() after converting the form to be ajax, using whatever method you use to do so. This is probably the easier of the two methods.

Rails query string in URL?

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.

form_for using :symbol not working, error [Only get, put, and delete requests are allowed]

When submitting a form to create a new object i get an error message when submitting the form. When i use the same form but then with an instance variable everything seems to go fine, any clue why the submit with the :symbol fails?
The error message says: Only get, put, and delete requests are allowed.
The code for the new form with :symbol is:
<% form_for :ecard do |f| %>
<%= label(:ecard, :title) %><br/>
<%= f.text_field :title, :tabindex => "1" %>
<%= f.submit "Create Ecard" %>
<% end %>
The form goes ok when i use
<% form_for #ecard do |f| %>
<%= label(:ecard, :title) %><br/>
<%= f.text_field :title, :tabindex => "1" %>
<%= f.submit "Create Ecard" %>
<% end %>
Some code out of my controller:
# GET new_ecard_url
# return an HTML form for describing the new ecard
def new
#ecard = Ecard.new
end
# POST ecard_url
def create
# create an ecard
#ecard = Ecard.new(params[:ecard])
if #ecard.save
flash[:notice] = "Succesfully created a new Ecard"
redirect_to :action => 'index'
else
flash[:warning] = "Error when saving Ecard"
render :action => 'new'
end
end
If the first argument is a symbol, it describes the object the form is about and name the instance variable, and then you need to provide the URL.
The actual object can be used and then it will use your routes to try and determine the URL. This means that it must know of a new_ecard_path and edit_ecard_path.
It will look at the object and see if it is a new record to determine which to use.
If you are using resource routes with the default restful routes, then you can probably just use the instance object. If you need to specify the URL that the form goes to, then use the symbol and specify the URL.
There are a few examples at http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
A good way to see what's going on is to use Firebug and inspect the generated HTML. If you don't have Firebug, get it now, it's really invaluable.
If you create your form using the instance variable, you'll get something along the lines of:
<form id="new_ecard" class="new_ecard" method="post" action="/ecards">
So this will create a POST request to the /ecards action, which is the create method (by the way, your comment above the create method should be POST ecards_url, not ecard_url, unless you've defined it otherwise).
However if you only use the :ecard symbol instead of the instance variable, you'll get:
<form method="post" action="/ecards/new">
Since you haven't specified a URL, it uses the current one. This means your form will call itself in this case, and nothing will happen.
All this is due to all the so called magic Rails does - convention over configuration. But as danivo said, you can specify the URL manually and explicitly state each parameter for the form if you do not want to have this magic happen for you.

Resources