0

Question? How do I get my form.submit button to use a specific route? Specifically, the user can fill out this form from any page, and it will submit to a desired controller.

ruby -v 2.3.0 rails 5.0

This form is a feedback form for users to submit feedback. The way it works is, a little icon is available to click so the user can fill out and submit this form from ANY page. The Problem is, unless the user is on the homepage (local/customers), for example, they're on post/13, the form tries to add its URL route on top of the example and I get a "no route matches" ...post/13/customers/questionaire.

This is my route.rb

        post 'customers/questionaire' => 'customers#questionaire'

This is the form view

     <%= form_for :anything, url: "customers/questionaire" ,multiple: 
    true do |form| %>


            <div><%= form.label :email, 'E-mail:' %>
              <%= form.text_field :email , placeholder: 'JohnDoe@yahoo.com' %>

            </div>

            <div><%= form.label :feedback, 'Type of feedback:' %>
              <%= form.text_field :feedback, placeholder: 'Problem, Bug, Idea...' %>
            </div>

            <div><%= form.label :notes, 'Notes: (Required)' %>
              <%= form.text_field :notes, class: 'notes', id: 'notes', placeholder: "Your Feedback" %>
            </div>

            <%= form.submit "Submit", class: "btn1", id: "button", disabled: true %>

      <% end %>
Mason SB
  • 445
  • 1
  • 3
  • 13

2 Answers2

1

I think you need something like this. Do http://localhost:3000/routes. You will get all the routes in your app

     <%= form_with scope: :post, url: customers_questionaire_path do |form| %>
        <%= form.text_field :title %>
     <% end %>

May be this for lower rails version :)

<%= form_for :customer, scope: :post, url: customers_questionaire_path  do |form| %>
        <%= form.text_field :title %>
        <%= form.submit %>
     <% end %>
praga2050
  • 729
  • 9
  • 18
  • This is a form with no model. This project uses ruby 2.3 and rails 5.0. I will update this in the settings. This didn't work unfortunately ... – Mason SB Apr 16 '18 at 16:57
  • this code also doesnt use any model. What is the error you are getting ? – praga2050 Apr 16 '18 at 16:58
  • I believe it is because of the version of ruby we are using.. undefined method `form_with' for #<#:0x007fb61ebe8260> Did you mean? form_tag – Mason SB Apr 16 '18 at 17:03
  • updated my answer. See if it helps. Thanks!. :customer can be anything – praga2050 Apr 16 '18 at 17:14
  • This is what ended up working #### => <%= form_for :anything, scope: :customer, url: customers_questionaire_path ,multiple: true do |form| %> – Mason SB Apr 16 '18 at 17:26
0

What matters is the action attribute of the form HTML element, or the formaction attribute of a button or input element.¹

In Rails it's defined like so:²

<%= form_tag("/search", method: "get") do %>
  <%= label_tag(:q, "Search for:") %>
  <%= text_field_tag(:q) %>
  <%= submit_tag("Search") %>
<% end %>

Which yields:

<form accept-charset="UTF-8" action="/search" method="get">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <label for="q">Search for:</label>
  <input id="q" name="q" type="text" />
  <input name="commit" type="submit" value="Search" />
</form>

This will send the form data to the /search route.

With this approach, each form of your page will use a different route as target for form processing. You could alternatively use the same route and treat multiple use cases inside a single route, but that's not what you're asking.


Alternatively (or in addition to) you can also use the formaction attribute in buttons and inputs, in which case you override the form element's action attribute:³

<%= form_tag("/search", method: "get") do %>
  <%= label_tag(:q, "Search for:") %>
  <%= text_field_tag(:q) %>
  <%= submit_tag("Search") %>
  <%= submit_tag("Search On Rails", formaction: search_on_rails) %>
<% end %>

Which yields:

<form accept-charset="UTF-8" action="/search" method="get">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <label for="q">Search for:</label>
  <input id="q" name="q" type="text" />
  <input name="commit" type="submit" value="Search" />
  <input name="commit" type="submit" value="Search On Rails" formaction="/search_on_rails" />
</form>

It's as if the first submit button had a formaction="/search" because it's ommited, therefore the action="/search" in the <form> is used.


Other approaches in this question's answers and this one.


For your use case, you'll have to make sure the route /customers/questionaire it's consistent in any URI level (absolute, not dynamic). I lack this particular knowledge in Rails to provide a failsafe solution for this case, although it seems it works as expected in the current default behavior.

So the mistake in your code is using url: with a relative URI when you really want an action: in this line:

<%= form_for :anything, url: "customers/questionaire" ,multiple: true do |form| %>

Use instead:

<%= form_for :anything, url: {action: "customers/questionaire"}, multiple: true do |form| %>

See this question and this one.


In addition to this, instead of hardcoding routes / urls in the code, there's the url_for helper: https://api.rubyonrails.org/v5.1.7/classes/ActionDispatch/Routing/UrlFor.html

Iuri Guilherme
  • 389
  • 1
  • 10