Posting a variable to another controller - ruby-on-rails

I have a welcome controller/view.
On the index.html.erb I have a simple form that takes in one value:
<%= form_tag do %>
<div>
<%= label_tag(:zip, "Enter Zipcode to search in:") %>
<%= text_field_tag(:zip) %>
</div>
<%= submit_tag("Search") %>
<% end %>
Upon hitting the submit button I'd like to pass the zip variable to another controller called "theaters". The variable doesnt need to be saved in any kind of model, its just being used to execute an API call in the Theaters controller.
Whats the simplest way to do this?
Thanks

Try this:
<%= form_tag({controller: "theaters", action: "index"}) do %>
<div>
<%= label_tag(:zip, "Enter Zipcode to search in:") %>
<%= text_field_tag(:zip) %>
</div>
<%= submit_tag("Search") %>
<% end %>
Hope it helps.

Make a route for your method in TheatresController, lets assume your method name is get_zip
post '/get_zip' => 'theaters#get_zip', as: "zip"
Create your form
<%= form_tag(url: zip_path, method: :post) do %>
<div>
<%= label_tag(:zip, "Enter Zipcode to search in:") %>
<%= text_field_tag(:zip) %>
</div>
<%= submit_tag("Search") %>
<% end %>
Access it inside your method:
def get_zip
#zip = params[:zip]
#your logic
end

Related

More efficent way to write this if statement? (Clean up code)

Originally, the idea was if the user had written a bio, show it on their profile. Otherwise, display a message.
<% if #user.bio.present? %>
<p class="user-bio"><%= #user.bio %></p>
<% else %>
<% if #user == current_user %>
<p class="user-bio">Press the green edit button and write something interesting about yourself.</p>
<% else %>
<p class="user-bio">Sorry, this user hasn't written anything about themselves yet.</p>
<% end %>
<% end %>
Then I thought of a way to improve this feature. Instead of making the user navigate to their settings page (devise/registrations/edit), let them edit their bio straight from their profile page (users/show).
To do this, the bio will be an input field that just looks like text, but when hovered over or clicked on, the user can see they can edit the text.
So I made this mock up version below and added resources to my user controller. But I get an error with the last else tag. I'm new to rails (and ruby) and I think this code is quite messy. Could someone with more experience help me write a better if statement that solves the same problem. I need a cleaner solution.
<% if #user.bio.present? %>
<p class="user-bio"><%= #user.bio %></p>
<% else %>
<% if #user == current_user %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| %>
<%= devise_error_messages! %>
<div class="input-group">
<%= f.text_field :bio, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit "Update", class: "btn-signin" %>
</div>
<% else %>
<p class="user-bio">Sorry, this user hasn't written anything about themselves yet.</p>
<% end %>
<% end %>
You don't need to nest a new if block inside of the first else.
Also, as #JoeC pointed out in the comments, you need a closing <% end %> for your form_for.
<% if #user.bio.present? %>
<p class="user-bio"><%= #user.bio %></p>
<% elsif #user == current_user %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| %>
<%= devise_error_messages! %>
<div class="input-group">
<%= f.text_field :bio, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit "Update", class: "btn-signin" %>
</div>
<% end %>
<% else %>
<p class="user-bio">
Sorry, this user hasn't written anything about themselves yet.
</p>
<% end %>
If you think this is still too much tag soup, you could put the form inside of a partial named _form.html.erb and render it. That way the main view template is focused on the logic of what to display rather than getting into the details of the form.
<% if #user.bio.present? %>
<p class="user-bio"><%= #user.bio %></p>
<% elsif #user == current_user %>
<%= render 'form' %>
<% else %>
<p class="user-bio">
Sorry, this user hasn't written anything about themselves yet.
</p>
<% end %>
The last thing that I'll point out is that you may want to switch around the first and second if tests. The way your logic is laid out, the user would never be able to edit their bio after they've entered one.
I agree 100% with Chris Peters. You can place the form code into a separate file called partial:
app/views/YOUR_CONTROLLER_NAME/_form.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name),
html: { method: :put, multipart: true }) do |f| %>
<%= devise_error_messages! %>
<div class="input-group">
<%= f.text_field :bio, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit "Update", class: "btn-signin" %>
</div>
<% end %>
Some information about partials you can find here: http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
If you decide to follow Chris's advice, you can transform the code further:
<% if #user.bio.present? %>
<p class="user-bio"><%= #user.name %></p>
<% else %>
<%= render 'form' if #user == current_user %>
<p class="user-bio">
Sorry, this user hasn't written anything yet.
</p>
<% end %>
Ruby If statements examples: Great Ruby Shorthands For If…Then…Else
You can also consider using content tags as below:
<% if #user.bio.present? %>
<%= content_tag(:p, #user.name, class: "user-bio") %>
<% else %>
<%= render 'form' if #user == current_user %>
<% no_bio_msg = "Sorry, this user hasn't written anything yet." %>
<%= content_tag(:p, no_bio_msg, class: "user-bio") %>
<% end %>
Hope this will help.

rails submit_tags to different actions

<%= simple_form_for#equipment, :url => equipments_path, :method => :post do |f| %>
....
<% if #equipment.id.present? %>
<div class="actions">
//TODO submit_tag to action Update
</div>
<% else %>
<div class="actions">
<%= submit_tag "Adicionar Equipamento" %>
</div>
<% end %>
<% end %>
In this example I have two buttons,if the object exists I have the first button and when not exists I have the second button. The second button send a request to controller Equipments#Create. How can I send a request to Equipments#Update in first button ?
<%= simple_form_for #equipment do |f| %>
<div class="actions">
<%= submit_tag(#equipment.persisted? ? "Create Equipment" : "Update Equipment") %>
</div>
<% end %>
This is the short way to do it.
Usually you would use I18n to translate these labels.
(see: I18n for model-specific Rails submit button)

Rails - passing arbitrary parameters into search

I have passed a value into a search page via -
<%= link_to 'add', users_path(bookto: #book.id) %>
in the view and
#book = Book.find_by_id(params[:bookto])
in the receiving controller action.
I have a search form in my receiving (index) view
<%= form_tag users_path(params[bookto: #book.id]), method: 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", name: nil %>
</p>
<% end %>
<%= "#{#book.id}, #{#book.title}" %>
<% if #users %>
<%= render partial: 'layouts/showusers', locals: {users: #users} %>
<% end %>
When I navigate through to the page
http://localhost:3000/users?bookto=1
The value of #book is passed properly. However, when I perform a search, the parameter is not being passed to
http://localhost:3000/users?utf8=✓&search=mysearch
I'm not passing the parameter through. I don't want to use this arbitrary parameter in the search, I just want it available to me to use once the search is complete. How do I achieve this? Do I need to add a search action to my controller?
Why don't just add a hidden field inside your search form like this
<%= form_tag users_path, method: 'get' do %>
<p>
<%= hidden_field_tag :bookto, #book.id %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", name: nil %>
</p>
<% end %>
Because you would want to see bookid in your URL anyway, so this method is ok in your case.

Undefined method - passing a value from one view to another

I have a form in a view similar to this:
<%= form_tag("mystuff/new", method: "get") do %>
<% #accesses.each do |access| %>
<%= radio_button_tag(:cost, access.cost) %>
<%= label_tag :label,access.label, :class=>"control-label" %>
<%= label_tag :costlabel, access.cost, :class=>"control-label" %> <%= label_tag :costlabel2, "Euros", :class=>"control-label" %>
<% end %>
<%= submit_tag "Go" %>
<% end %>
My controller has:
helper_method :amount
def new
#amount = params[:cost]
end
and the view of mystuff/new has a line like:
<div class="row-fluid offset1">Stuff: <%= amount -%> </div>
I get Error undefined method `amount'. What I want to do is pass the value of the radio button to the next view, but I don't want to use a database. What's the proper way to do that in rails?
You are missing a # here. #amount.

How to submit multiple, duplicate forms from same page in Rails - preferably with one button

In my new views page I have:
<% 10.times do %>
<%= render 'group_member_form' %>
<% end %>
Now this form contains the fields: first_name, last_name, email_address and mobile_number. Basically I want to be able to fill in the fields of all the forms in one click which then submits each into the database as a unique row/id.
What would be the easiest way to accomplish this?
Note: The number of times do is called from a variable. Any advice welcome, thanks!
You should have only one form (you should put only fields in the group_member_form partial). In your view you should have something like:
<%= form_tag "/members" do %>
<% 10.times do %>
<%= render 'group_member_form' %>
<% end %>
<%= submit_tag "Submit" %>
<% end %>
and in _group_member_form.html.erb you should have
<%= text_field_tag "members[][first_name]" %>
<%= text_field_tag "members[][last_name]" %>
<%= text_field_tag "members[][email_address]" %>
<%= text_field_tag "members[][mobile_number]" %>
This way, when the form submits, params[:members] in the controller will be an array of member hashes. So, for example, to get the email adress from the fourth member after submitting the form, you call params[:members][3][:email_adress].
To understand why I wrote _group_member_form.html.erb like this, take a glance at this:
http://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions.
You can also use accepts_nested_attributes_for in your model, and use fields_for on your form.
Submitting multiple forms, afaik, only javascript, if the forms are remote: true, and you run through each of them and then submit.
$("form.class_of_forms").each(function() {
$(this).submit();
});
Alternatively a more up to date approach using form_with and fields_for, without removing the form into a partial, could be written like this:
<%= form_with (url: end_point_path), remote: true do |form| %>
<% (1..5).each do |i| %>
<%= fields_for 'cart_items'+[i].to_s do |fields|%>
<%= fields.text_field :first_name %>
<%= fields.text_field :last_name %>
<%= fields.email_field :email_address %>
<%= fields.number_field :phone_number %>
<% end %>
<% end %>
<%= form.submit "Submit" %>
<% end %>

Resources