form_with producing wrong controller (only on some routes)? - ruby-on-rails

This is in application.html.erb, and it works on 95% of the pages in my app:
<% ['usd', 'eur', 'aud'].each do |currency| %>
<%= form_with url: {controller: :home, action: :currency_select}, method: :post do |currency_form| %>
<%= currency_form.hidden_field :preferred_display_currency, value: currency %>
<%= currency_form.submit currency, class: "btn-info shadow-none" %>
<% end %>
<% end %>
But when I visit a certain view, before the page even loads, it gives this error:
ActionView::Template::Error (No route matches {:action=>"currency_select", :controller=>"users/home"}):
191:
192: <%= form_with url: {controller: :home, action: :currency_select}, method: :post do |currency_form| %>
193: <%= currency_form.hidden_field :preferred_display_currency, value: currency %>
194: <%= currency_form.submit currency, class: "btn-info shadow-none" %>
195: <% end %>
196:
197: <% end %>
I'm pretty sure something to do with :controller=>"users/home" (where it should simply be :controller=>"home")
Why is the form suddenly confused about the controller?

Solution 1
Run
rails routes | grep currency
it returns
currency_select POST /currency_select(.:format)
home#currency_select
Now just use url: currency_select_path like so:
<% ['usd', 'eur', 'aud'].each do |currency| %>
<%= form_with url: currency_select_path, method: :post do |currency_form| %>
<%= currency_form.hidden_field :preferred_display_currency, value: currency %>
<%= currency_form.submit currency, class: "btn-info shadow-none" %>
<% end %>
<% end %>
Solution 2
Replace :home with "/home":
<% ['usd', 'eur', 'aud'].each do |currency| %>
<%= form_with url: {controller: "/home", action: :currency_select}, method: :post do |currency_form| %>
<%= currency_form.hidden_field :preferred_display_currency, value: currency %>
<%= currency_form.submit currency, class: "btn-info shadow-none" %>
<% end %>
<% end %>
(not totally sure why that works, but can confirm that it indeed works!)
A work around
The above two solutions are best, but a work around for the problem could be:
<% if !current_page?(edit_user_registration_path) %>
# all existing code
<% end %>
This way it simply avoids displaying the form on the route that errors. It's not ideal, but a practical work around.

Related

How to change the content of rendered layout in rails?

Have to render the form that already exist in the project inside the page, but with a different title
app/views/welcome
<div class="form-wrapper>
<%= render 'form/form_variants/register_1', register: #register %>
</div>
-----------
app/views/form/form_variants/register_1
<%= form_for register.user, as: :user, url: register_path(service: params[:service]), method: :post %>
<%= content_tag :div, class: html_class('simpleFormHeading') do %>
<%= content_tag :h1, t('signup.title_register') %> #title that should be changed
<%= content_tag :p, raw(t('login.account_login.text', login_link: login_link)) %>
<% end %>
#a lot of inputs
<% end%>
Thanks in advance for your reply!
I would pass it as another variable to the partial
<div class="form-wrapper>
<%= render 'form/form_variants/register_1', register: #register, signup_title = 'whatever' %>
</div>
# app/views/form/form_variants/register_1
# optional: init signup_title to a default value depending on your needs
<% signup_title ||= t('signup.title_register') %>
<%= content_tag :h1, signup_title %>

Link does not 'post' the right data to action. (only get last id)

I have a page that lists all news articles and an edit button beside them (manage). The edit button takes you to the edit page and sends the data of its respective article. The edit button always chooses the last id generated. What am I doing wrong with my loop?
Resources:
routes.rb
get '/news/manage', to: 'news#manage'
match '/news/edit', to: 'news#edit', :via => :post
news_controller.rb
before_action do
setup(session[:current_user_id])
end
def edit
#article = News.find(params[:id])
end
def manage
end
private
def setup(session)
#user = User.find(session)
#articles = News.all
end
manage.html.erb
<%= form_tag '/news/edit', method: "post" do %>
<%= #articles.each do |article| %>
<%= content_tag :button, type: "submit" do %>
<%= content_tag :i do %><%end%>
<%end%>
<%= content_tag :input, name: "id", value: article.id do %> <%end%>
<%end%>
<%end>
edit.html.erb
<%= content_tag :textarea, name: "content", rows: "20" do %>
<%= #article.content.gsub(/\s+/, " ")%>
<%end%>
<%= content_tag :input, name: "id", type: "hidden", value: #article.id do %> <%end%>
First make following change in routes.rb
replace
match '/news/edit', to: 'news#edit', :via => :post
with
get '/news/:id/edit' => 'news#edit', as: :edit_news
then replace
<%= form_tag '/news/edit', method: "post" do %>
<%= #articles.each do |article| %>
<%= content_tag :button, type: "submit" do %>
<%= content_tag :i do %><%end%>
<%end%>
<%= content_tag :input, name: "id", value: article.id do %> <%end%>
<% end %>
<% end %>
with
<%= #articles.each do |article| %>
<%= link_to "Edit", edit_news(article) %>
<% end %>
this will create `Edit` link for each article and clicking on it will take you to edit page.
If you want to show link as button you need to write css.
The problem is that your form has multiple generated elements with the same name : "id". It doesn't know which one to use, so it uses the last one.
Now the thought....how do you make the name unique for each article? This probably isn't the best solution but...don't
Make your form unique. Change this code:
<%= form_tag '/news/edit', method: "post" do %>
<%= #articles.each do |article| %>
<%= content_tag :button, type: "submit" do %>
<%= content_tag :i do %><%end%>
<%end%>
<%= content_tag :input, name: "id", value: article.id do %> <%end%>
<%end%>
<%end>
to this:
<%= #articles.each do |article| %>
<%= form_tag '/news/edit', method: "post" do %>
<%= content_tag :button, type: "submit" do %>
<%= content_tag :i do %><%end%>
<%end%>
<%= content_tag :input, name: "id", value: article.id do %> <%end%>
<%end%>
<%end>

How do i route a particular controller action to a particular form in rails?

Hi I am new to RoR and I was making a simple math_app. The addition function works fine. Now I'm trying to do a simple subtraction.The subtract controller is invoked and the subtract form is displayed but when I click on subtract the add controller gets invoked and an addition is performed. Where have I gone wrong?
This is my routes.rb:
Rails.application.routes.draw do
get 'subtract/form'
post 'subtract/result'
get 'add/form'
post 'add/result'
end
result.html.erb:
<%= #first %> - <%= #second %> = <%= #result %>
<br/>
<%= link_to 'back', subtract_form_path %>
form.html.erb: (This is the subtraction form)
<%= form_tag subtract_result_path do %>
<%= number_field_tag :first %>
-
<%= number_field_tag :second %>
<%= submit_tag "subtract" %>
<% end %>
subtract_controller.rb:
class SubtractController < ApplicationController
def form
end
def result
#first = params[:first].to_i
#second = params[:second].to_i
#result = #first - #second
end
end
You have problem in views/substract/form.html.erb. It now reads:
<%= form_tag add_result_path do %>
<%= number_field_tag :first %>
-
<%= number_field_tag :second %>
<%= submit_tag "subtract" %>
<% end %>
But it should be:
<%= form_tag substract_result_path do %>
<%= number_field_tag :first %>
-
<%= number_field_tag :second %>
<%= submit_tag "subtract" %>
<% end %>
You should probably also fix route
post '/subtract/result' => 'subtract#result', as: 'substract_result'
Also in views/substract/result.html.erb:
<%= #first %> - <%= #second %> = <%= #result %>
<br/>
<%= link_to 'back', subtract_form_path %>

Ruby Rails is it possible to check before displaying form?

Is it possible to check submission before showing this simple form:
<%= form_for #article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body, size: "60x12" %>
<%= f.submit "Create" %>
<% end %>
like if its already submitted first time show other html content instead ?
Test the object. If you're using ActiveRecord/Mongoid:
<% if #article.new_record? %>
... display form ...
<% else %>
... do something different ...
<% end %>

correct syntax for form_for url in rails

This is probably simple, I'm still coming to terms with rails syntax. What is the right syntax to pass the address_id in the url for form_for to a modified route?
This is the form - note the "address_id parameter"
<div class="one_fourth floatcenter">
<%= form_for address, :url => edit_address_path(:id => address.id), :method => :get do |f| %>
<%= content_tag(:button, :class => 'btn btn-inverse') do %> Edit Address
<% end %>
<% end %>
</div>
And this is the route I've configured:
get "edit_address/:id" => "member/addresses#edit"
Id is not being passed to the controller for some reason...
form_for address should be enough if address is a persisted object, but if it's not enough, then form_for address, url: edit_address_path(address) is what you want.
This is very simple. In place of url, you put your post method route:
<%= form_for(#post, url: super_posts_path) do |f| %>
...
<% end %>
You also call by action
<%= form_for #friend,:url=> { action: "create_friend"} do |f|%><br>
<%= f.label :u_from %>
<%= f.text_field :u_from %>
<%= f.label :u_to %>
<%= f.text_field :u_to %>
<%= f.submit%>
<% end %>

Resources