How to params[] value to a user-defined action - ruby-on-rails

I have a form named purchase_products.html.erb
<%= form_for (:purchase) do |f| %>
<% for product in #purchase %>
<%= check_box_tag "product_ids[]", product.id %>
<%= product.product_name %> |
<%= product.description %> |
<%= product.link %> |
<%= link_to 'Show', product_path(product) %><br/>
<% end %>
<%= f.submit "Purchase" %>
<%= link_to 'Home', :start %>
<% end -%>
Here when I click the submit button I want to send all selected checkboxes values to a action 'my_purchase' in purchase controller.
How do i redirect my button to call my user defined method?
and how can I do to retrieve which checkboxes are selected?

Add url params to form_for. See form_for API
<%= form_for(:purchase, :url => {:action => :user_defined_method}) do |f| %>
You can access the checkboxes as an array of product ids in the method as params[:product_ids].

Related

Rails: How to pass array from view to controller with button_to

I'm new to rails. What I'm trying to do is to design an order system. It lists a bunch of items and each item is followed by a select box so that people can choose the number that they want to order. My question is how to pass this count[] array and the corresponding item id from view to controller using button_to. Thank you for any suggestions.
<% #items.each do |item| %>
<li>
<%= link_to item.name, item %>
<%= select_tag 'count[]', options_for_select([0,1,2,3,4,5])%>
</li>
<% end %>
<%= button_to 'Place Order', orders_confirm_path, method: :post, params: { ??? } %>
You use the tag multi-select.
example in your view. For can select multi with ctrl + click at item:
<%= form_tag orders_confirm_path, method: :post %>
<label>select more than one with ctrl + click at item</label>
<p><%= select_tag :items, Item.all.collect {|item| [item.name, tem.id]}, {prompt: "Select item"}, multiple: true %></p>
<p><%= button_to 'Place Order'%></p>
and your controller you can receive the parameters in this way:
def create
#order = Order.new(params[:items])
if #order.save
code ...
else
code ...
end
end
You can this using form like below
<%= form_tag orders_confirm_path, method: :post do %>
<% #items.each do |item| %>
<%= hidden_field_tag :item_id, value: item.id %>
<li>
<%= link_to item.name, item %>
<%= select_tag 'count[]', options_for_select([0,1,2,3,4,5])%>
</li>
<% end %>
<%= button_to 'Place Order' %>
<% end %>
Now you can find on controller params[:count] params[:item_id]
Hope to help

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.

Multiple fields not display in single form and model Rails

I have model product. I want to create multiple record in single model (product), but fields not display in view
#controller
#products = Array.new(3){ Product.new }
# view
<%= form_tag create_product_path, :method => :post, :class => "form-horizontal", 'role' => "form" do %>
<% #products.each_with_index do |product, index| %>
<% fields_for "products[#{index}]", product do |f| %>
<%= f.text_field :date %>
<%= f.text_field :name %>
<% end %>
<% end %>
<%= submit_tag "Submit", :class => "btn btn-primer" %>
Look at this screenshoot, fields not appear. Can anyone tell me, why new form method using array not appear?
Don't forget about <%= on fields_for
read about fields_for
rails 2.x - 3.0
<% fields_for "products[#{index}]", product do |f| %>
rails > 3.1.x
<%= fields_for "products[#{index}]", product do |f| %>

Changing button value of a scaffold when in /new and /edit in rails

I generated a Stories scaffold and now when I'm in stories/new, the button that I click says "Create Story." How do I change the value of that to say something else, like "Create Tale"?
I've gone into the stories/new.html.erb and also the stories/edit.html.erb, but all that is there is
<%= render 'forms' %>
When I head to stories/_form.html.erb there is a
<div class="actions">
<%= f.submit class: "btn" %>
</div>
I know you can put <%= f.submit "Create Tale", class: "btn" %>, but if I do that it will say "Create Tale" for both creating and updating. How could I make is also say "Update Tale" for when I'm in stories/edit?
For giving it a name, try:
<%= f.submit class: "btn", name: "Create Tale" %>
For naming it differently depending on the action. What I normally do is pass the button-name into the form-template from the action-view.
Eg in new.html.erb:
<%= render partial: 'form', button_name: 'Create Widget' %>
in edit.html.erb:
<%= render partial: 'form', button_name: "Update Widget" %>
in form:
<%= f.submit name: button_name %>
The alternative is not to put the submit buttons in the "form" partial, but to keep them in the action-views eg for "new.html.erb"
<%= form_for #widget do |f| %>
<%= render partial: 'form' %>
<%= f.submit name: 'Create Widget' %>
<% end %>
for "edit.html.erb"
<%= form_for #widget do |f| %>
<%= render partial: 'form' %>
<%= f.submit name: 'Update Widget' %>
<% end %>
NOTE: code not tested and probably buggy, but you get the drift...
work directly on the form (partial _form)
<%= f.submit "Submit", class:"btn"%>
For Rails 5, change:
in new and edit views
and
the same way.
Then in form use:
instead of

current action name problem

When i am in /edit action, i see edit button but the problem is if there is an error in form validation it renders action edit and i see create button. how can i fix it?
<%= form_for(#page) do |f| %>
<% if controller.action_name =="edit" %>
<%= f.submit "Update" %>
<% else %>
<%= f.submit "Create" %>
<% end %>
<% if ["edit", "update"].include? params[:action] %>
<%= f.submit "Update" %>
<% else %>
<%= f.submit "Create" %>
<% end %>
Better solution is to extract your form as a partial and send local variable with button name to it
your edit view:
<%= render :partial => "form", :locals => { :button_label => "Edit" } %>
your create view:
<%= render :partial => "form", :locals => { :button_label => "create" } %>
your _form partial:
<%= form_for #object ... do |f| %>
...
<%= f.submit button_label %>
<% end %>
UPD
I think #idlefingers solution the best for your issue
You could just use f.submit with no arguments. This will create names like "Update Page" and "Create Page". If you want to change the wording of these, they can be set in your locale. No conditionals, no messing about with action names. Simple.
Try to do this check:
<%= form_for(#page) do |f| %>
<% if controller.action_name =~ /update|edit/ %>
<%= f.submit "Update" %>
<% else %>
<%= f.submit "Create" %>
<% end %>
My solution:
<%= form_for(#page) do |f| %>
<%= f.submit(f.object.new_record? ? "Create" : "Update") -%>
<% end %>

Resources