Generating a form that passes multiple parameters - ruby-on-rails

I have the following in my routes.rb
map.diff 'posts/:id/diff/:from/:to', :controller => "posts",
:action => "diff", :conditions => { :method => :get }
And I have the following in my view file.
- form_tag(diff_path(), :method => :get) do
= text_field_tag(:from, "")
= text_field_tag(:to, "")
= hidden_field_tag(:id, #post.id)
= submit_tag("Submit")
I would like to generate a form that submits something like "http://example.com/posts/3/diff/13/18", but it fails. How can I make such a form?
I need to pass parameters for diff_path(), but I don't know how to do that. I don't even know if this is possible with form_tag.
The error message:
diff_url failed to generate from {:action=>"diff", :controller=>"posts"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: ["posts", :id, "diff", :from, :to] - are they all satisfied?

To my knowledge, what you're trying to accomplish can't be done with just an HTML form. The reason being that the form will only know how to submit traditionally via GET and POST. It has no knowledge of the structure of the URL.
You get that error message because the :id, :from and :to parameters are required to form the both you want, so when you call diff_path() it freaks out.
Personally, I would advise you not to use the URL structure you're planning on - however I'm not totally clear on what this page is going to display. Regardless, if the :from and :to parameters are algorithmic input and not resource identifiers, I would avoid this structure.
That said, if you do want to implement this, you would either have to implement a redirect from rails or javascript.
Rails method
#some_controller.rb
redirect_to diff_path(:from => params[:from], :to => params[:to])
Javascript (jQuery) method
$(function() {
$("form#your_form_id_here").submit(function() {
window.location = "posts/" + this.id + "/diff/" + this.from + "/" + this.to;
return false;
});
});

I don't think that will work by specifying the url with that format in the form. Rails tries to create the URL to submit to when you render the page, not when you submit the form. So it is not seeing those parameters when you render the page. I would recommend creating another route
map.diff_form 'posts/:id/diff', :controller => :post, :action => :diff, :conditions => {:method => :post}
You could use the two routes side by side if you need to keep the current url format.

Why are you trying to do this in the first place? I really can't think of a good reason why this would be necessary.
Your "from" and "to" variables should probably just be normal URL parameters - i.e. /posts/:id/diff?from=X&to=Y, so that you can then retrieve them in your controller with params[:from] and params[:to]
There may be a way to make Rails work this way, but you're going to have issues with it, since Rails is emphatically not meant to work this way.

I think you can use like this
diff_path(#id,#from, #to)
where #id, #from, #to are instance variables. If dont, you can specify a hash also like
diff_path(:id=>#id,:from=>#from, :to=>#to)

Related

Call a method from a form - rails

I have a form to upload a file. I want to call a particular method in my controller when I press my submit button. This is probably a really simple thing but I'm really new to rails.
I have a method in my videos_controller called "upload_translation_handwritten"
Here is my form:
%form{role: 'form'}
.form-group
%label.h4{for: "handwrittenTranslation"} Upload Handwritten Translation
%input#inputFile{name: 'translation', type: "file"}
%button.btn.btn-default{type: "submit"} Upload
I have a route:
match 'users/:id/videos/:video_id/translate_video_handwritten' => 'videos#upload_translation_handwritten', via: 'post', as: :upload_translation_handwritten
I'm already at 'users/:id/videos/:video_id/translate_video_handwritten' and I want to call this other method that does a couple things then redirects to the same page with a little flash message. Right now, when I click "upload", nothing happens :(
Thanks in advance!
rails convention
check form action(routing) and method(post)
<form action="this" method="and this">...</form>
in routes.rb
match "**/videos/:video_id" => "vidoes#edit", :as => :get # upload form as html
match "**/videos/:video_id/upload" => "videos#upload", :as => :post # upload and redirect with flash
in videos_controller.rb
def upload
...
flash[:msg] = "Not suppported video format"
render "edit"
end
in upload_form.html.haml
- if flash[:msg]?
= flash[:msg]
You need to add url for attribute action. In your case, I think it is %form{role: 'form', action: upload_translation_handwritten_user_video_path(user_id, video_id), method: :post}. Please run rake routes to see right named helper
Your route points out to the POST method only,
You have to accept it for GET method also.
Change your route to
match 'users/:id/videos/:video_id/translate_video_handwritten' => 'videos#upload_translation_handwritten', as: :upload_translation_handwritten
Then You can able to view your Form, No need to give action in your form,
After Update Your Controller like this
def upload_translation_handwritten
# Perform Your actions for both GET and POST
# check with
if request.post?
# Add codes for actions after submission of form
else
# render your form
end
end
I ended up fixing it by changing:
%form{role: 'form'}
TO
=form_tag(:action => 'upload_translation_handwritten', :method => 'post')
Thank you everyone for your help!!

Routing error Rails 3.2.1

I'm trying to create a very simple site the sends and receives parameters from the URL (or link), the app should support any number of parameters, i.e. http://localhost:3000/action=receive&controller=pages&email=mail%40site.com&name=Vinny, and then be able to receive/print them.
I think I have located the problem to my route. It currently looks like this:
match 'pages/*params' => 'pages#receive'
I create the link that sends the params like this:
<%= link_to "Send Params", :action => "receive", :name => "Vinny", :email => "mail#site.com" %>
When I click the link I get the following error.
No route matches [GET] "/assets"
And the URL looks like this:
http://localhost:3000/assets?action=receive&controller=pages&email=mail%40site.com&name=Vinny
Note asset?.
If my route instead looks like this:
match 'pages/:name/:email' => 'pages#receive'
It works, but then I'm limited to the specified params.
Any tips on how to solve this would be great.
Okay, I think I see what is happening. Specifying parameters in the routes is not necessary to get the values into the controller's action. So, replace the map you specified earlier in the routes.rb with
resources :pages
If you add to your link
:controller => "pages"
It should go to the correct controller + action. (this may not be necessary in your case)
In that action, you can grab all of the params from the hash
email = params[:email]
account = params[:name]
Etc.
Info on routing
Info on params

Passing id in form_for action

I have a form to update an attribute of a model - I don't want it to go to the standard update action I want it to go to a different action.
<% for car in #cars %>
<%= form_for car, :url => { :action => "custom_action/#{car.id}" } do |f| -%>
This is giving the following error -
No route matches {:action=>"custom_action/1", :controller=>"cars"}
However if I visit the url - custom_action/1 - I don't get the routing error.
Any idea why I can't do this?
In addition to what Frederick Cheung said about GET vs POST vs PUT, I think your code might be wrong in general.
To do exactly what you want, try:
form_for car, :url => {:action => "custom_action", :id => car, :controller => "cars"} do |f|
I don't think this is a good idea, and will probably cause you pain. I suggest taking a look at the Ruby on Rails Routing Guide, to understand how to do this properly. (Routing is a topic where I always have to consult the manual.)
With correct routes your code should look something like this:
form_for car, custom_action_car_path(car) do |f|
Which will be easier to change in the future if/when you refactor your app.
If you go to the url by typing it into the url bar, you're making a GET request, whereas forms emit POST requests by default, and in this case would probably emit a PUT request (since you're acting on an existing record).
It sounds like your route is only routing GET requests. Given that you say your custom action does update the record, it sounds like you should update your routes to accept PUT requests instead.

Using named routes with parameters and form_tag

I'm trying to create a simple search form in Rails, but I think I'm missing something.
I have a named route for search:
map.search ":first_name/:last_name", :controller => "home", :action => "search"
I'm trying to use that in my search form:
<% form_tag(search_path, :method => 'get') do %>
<%= text_field_tag(:first_name) %>
<%= text_field_tag(:last_name) %>
<%= submit_tag("Search") %>
<% end %>
But when I load up the search form I get an ActionController::RoutingError:
search_url failed to generate from {:action=>"search", :controller=>"home"} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: [:first_name, :last_name] - are they all satisfied?
What am I missing? I thought the fields defined in my form would be automatically linked up with my route parameters. :-/
Update:
I understand that search_path is generated before the form is displayed now, so it can't be updated. Obvious in hindsight!
I changed my routes:
map.search 'search', :controller => "home", :action => "search"
map.name ':first_name/:last_name', :controller => "home", :action => "name"
And now the search action just does:
def search
redirect_to name_path(params)
end
It all works a treat! The main goal here was getting that URL from the name named route as result of doing a search. Thanks guys!
form_for generates form and it has to have specified all parameters that are needed to create search_path, so it should look like:
<% form_tag(search_path, :firstname => 'some_text', :lastname => 'some_text', :method => 'get') do %>
or at least something like this. HTML tag form has parameter action='/some/url' and that's why you have to specify all parameters for search_path. But the above example won't work as you expected.
So what you can do?
Create empty form that has action='/' and with js replace it with content of your input text fields before submitting.
Create another route, on example /search that recives parameters from submit and then redirects to correct path.
Probably there is also some better ways to do it ;)
First, search_path is actually a method, which takes a hash of options. It is this method which should receive :first_name and :last_name.
Second, a browser can only submit form parameters as the body of a POST request, or as query string parameters (for any kind of request method). So there's unfortunately no way a browser's native submit function can generate that kind of URL.
Another way of thinking of it: What you're doing here is filling the form tag's action attribute with an URL. Rails needs a complete URL as you're building the form. So all parameters in your route need to be specified when the form helper is called, rather than at the next POST request.
So unfortunately, what you're trying to do is not possible in a normal Rails application.
(If you really want to, you might be able to pull it off by writing your own form helpers and a bit of Javascript to replace the browser's native submit function. The Javascript would then construct that URL based on the form fields. I'd argue against it, though.)

Generate URL in Grails

I need to pass a correct URL to a javascript function in one of my GSPs. I don't want to just hard code it just in case the mappings for that URL ever change.
I know in Rails I would use the url_for method such as:
<%= url_for :controller => 'something', :action => 'edit', :id => 3 %>
How would I do this in Grails? I can't seem to find a GSP tag or anything that would return a properly formatted URL given the controller, action, id, etc...
Use createLink, see http://grails.org/doc/1.2/ref/Tags/createLink.html

Resources