Is it possible to send params in a form URL - html

I can send the param x=y in a form with a hidden field like this
<%= form_with(url: '/search', method: 'get') do %>
<%= text_field_tag(:query) %>
<%= hidden_field_tag(:x, 'y') %>
<%= submit_tag("Search") %>
<% end %>
Is it possible to send params in the URL? The following doesn't work
<%= form_with(url: '/search?x=y', method: 'get') do %>
<%= text_field_tag(:query) %>
<%= submit_tag("Search") %>
<% end %>

As you can read here, the query string that you might have in a HTML form action attribute will not taken into account.
Translated into your form_for problem, it means that the query string that you have in your url: are not taken into account.
Hence, your hidden_field_tag is the right solution for this problem.

Related

No route matches [POST] when using a form_with with a post request

I'm trying to send a simple information to my controller using a form_with, but the application doesn't identify my post type route even though it's created.
#routes.rb
Rails.application.routes.draw do
https://guides.rubyonrails.org/routing.html
get 'report_client', to: 'report_client#index'
post 'report_client', to: 'report_client#create'
root "home#index"
end
#view
<%= form_with url: "report_client_path", method: :post do |f| %>
<%= f.label :salary, "Salary: " %><br><br>
<%= f.text_field :salary %>
<button type="submit">Enviar</button>
<% end %>
#controller
class ReportClientController < ApplicationController
def index
end
def create
end
end
#rails routes
Path / Url HTTP Verb Path Match Controller#Action
report_client_path GET /report_client(.:format) report_client#index
POST /report_client(.:format) report_client#create
root_path GET / home#index
Replace "report_client_path" to report_client_path. Just remove double quotes for report_client_path helper.
<%= form_with url: report_client_path, method: :post do |f| %>
<%= f.label :salary, "Salary: " %><br><br>
<%= f.text_field :salary %>
<button type="submit">Enviar</button>
<% end %>
You're passing the string literal "report_client_path" instead of calling the method report_client_path which means that the form will have action="/report_client_path" instead of report_client. Remove the quotes or use the correct string literal.
<%= form_with url: report_client, method: :post do |f| %>
<%= f.label :salary, "Salary: " %><br><br>
<%= f.text_field :salary %>
<%= f.submit "Enviar" %>
<% end %>

How can I filter a specific params key from params passed in a link_to?

I have an index where users can apply many different kinds of filters through checkboxes.
Each filter has an "X" link_to button that dismisses the filter, which basically makes a request to the same index page permiting the current params with the exception of the dismissed filter's param key.
For example:
<div class="form-group <%= 'hidden' unless params.dig(:q, "subscription_payment_type_eq").present? %>" id="subscription_payment_type_eq" data-toggle-target="objective">
<%= f.select :subscription_payment_type_eq, payment_types_selector_for_filter, { include_blank: "Forma de pago..."}, class: "form-control gray my-2 " %>
<% if params.dig(:q, "subscription_payment_type_eq").present? %>
<%= link_to admin_users_path(params: params.permit(q: [:extra_params, :address_province_eq, :subscription_status_eq, :created_at_gteq, :created_at_lteq])) do %>
<span class="dismiss-box glyphicon glyphicon-remove-circle">
<% end %>
<% end %>
</div>
<div class="form-group <%= 'hidden' unless params.dig(:q, "address_province_eq").present? %>" id="address_province_eq" data-toggle-target="objective">
<%= f.select :address_province_eq, user_provinces_selector_for_filter, { include_blank: "Provincia..."}, class: "form-control gray my-2 " %>
<% if params.dig(:q, "address_province_eq").present? %>
<%= link_to admin_users_path(params: params.permit(q: [:extra_params, :subscription_payment_type_eq, :subscription_status_eq, :created_at_gteq, :created_at_lteq])) do %>
<span class="dismiss-box glyphicon glyphicon-remove-circle">
<% end %>
<% end %>
</div>
The approach works, but it's very cumbersome to manually add the excepted param key to each new filter that is added to the index page.
Is there a way to pass params excluding the param key that belongs to the filter being dismissed?
I've tried the following but no params are passed:
<% if params.dig(:q, "subscription_payment_type_eq").present? %>
<%= link_to admin_users_path(params: params[:q].except(:subscription_payment_type_eq).permit) do %>
<span class="dismiss-box glyphicon glyphicon-remove-circle">
<% end %>
<% end %>
Also tried this but got undefined method 'exclude' for #<ActionController::Parameters:0x00007f6331b00dd8>
<%= link_to admin_users_path(params: params.exclude(:subscription_payment_type_eq).permit) do %>
Permit expects a list of args and since you're not sending any no params will be passed to your controller. I'm actually not sure how your calling permit without args is even working. Anyway maybe you can try it like this instead:
<%= link_to admin_users_path(params: params[:q].except(:subscription_payment_type_eq.permit!)
In the end we decided to implement it this way:
<%= link_to admin_users_path(
params: { q: params.require(:q).permit(params[:q].keys - ["address_province_eq"]) }
) do %>
We basically substract the filter's key from the current params when passing it in the link_to

Hash being saved to database but unable to render its values in Rails forms?

I added a new column to model Plan, named :per_unit_quantities_configuration which is a hash with min, max and step key/values.
t.jsonb "per_unit_quantities_configuration", default: {}
When I edit a Plan, the hash is being correctly saved to the DB (I can access each key/value from the console), but the forms are not displaying any of its values (the fields are empty).
I tried adding a store_accessor for the column in the Plan model, but it is not working:
store_accessor :per_unit_quantities_configuration, :min, :max, :step
Example of a simple_form html that does not display hash values:
<%= simple_form_for [:admin, #base_plan, #plan] do |f| %>
<% if f.object.base_plan.per_unit? %>
<div class="d-flex">
<%= f.simple_fields_for :per_unit_quantities_configuration do |fields| %>
<% if f.object.errors[:per_unit_quantities_configuration].any? %>
<%= f.error :per_unit_quantities_configuration, id: "per_unit_price_error", class: "invalid-feedback", error_prefix: "gato" %>
<% end %>
<%= fields.input :min %>
<%= fields.input :max %>
<%= fields.input :step %>
<% end %>
</div>
<% end %>
<%= f.button :submit, class: "pull-right" %>
<% end %>
What am I doing wrong?
since you setup store_accessor :per_unit_quantities_configuration then you can access directly 3 attributes min, max, step, so that you no need to wrap those attributes on simple_fields_for :per_unit_quantities_configuration and treat them as normal fields (that mean on controller you have to permit them as normal fields)
# view
<%= f.input :min %>
<%= f.input :max %>
<%= f.input :step %>
# controller
def plan_params
params.require(:plan).permit(:min,:max,:step)
end

Ruby on Rails how to include a form in an index view

I've been running my head into a wall for hours now and I can't make this work. I'm trying to add a bunch of check boxes to verify items on my index page. I found this old rails cast that does exactly what I want to do, but I've run into a problem. Anything enclosed inside my form is removed from the index page, like just gone poof. Here's the code from the index view.
<% form_tag verify_products_path, :method => :put do %>
<% #products_unverified.each do |products| %>
<% if product.deleted != 'true' %>
<tr data-link="<%= product_path(product) %>">
<td><%= product.name %></td>
<td><%= product.description %></td>
</tr>
<% end %>
<% end %>
<%= submit_tag "Mark as Verified" %>
<% end %>
</tbody>
Here's the routes stuff
resources :products do
put :verify, :on => :collection
end
and the controller just has a dummy method for now.
def verify
end
Any clue as to why the index view blanks out when the form is introduced? Any help is much appreciated.
You forgot the = before form_tag:
<%= form_tag verify_products_path, :method => :put do %>
put an = in front of form_tag
instead of
<% form_tag verify_products_path, :method => :put do %>
try
<%= form_tag verify_products_path, :method => :put do %>

Accessing elements between forms

I am trying to access the value of an element in a different form. More specifically I have two forms, one normal html form which submits the information, and an ajax form that updates a field in the database. I want the ajax form to take the value of an element in the normal form, but I have no idea how to accomplish that. Here is my current setup:
Message View
<%= form_for #message do |f| %>
<%= f.text_field :to %>
<%= f.text_area :body %>
<%= f.submit "Send Message" %>
<% end %>
<%= form_for :save, :url => save_message_path(), :remote => :true do |f| %>
<%= f.submit "Save" %>
<% end %>
Message Controller
def save
account.message = params[:body]
end
But the :body param is in the other form so it sets account.message to nil because the ajax form did not have a body parameter. I would like it so the ajax form can submit the value of the body element.
Since the form is edited on the client side, you'll have to write this functionality in javascript.
It is relatively straightforward to copy the value of the message body into a hidden field and submit the Ajax form. This would be most easily accomplished by adding an id your ajax form as follows:
<%= form_for :save, :url => save_messages_path(), :remote => true, :id => 'ajaxform' %>
<%= hidden_field_tag 'hidden_message' %>
Then in javascript you could do the following:
$(document).ready(function(){
$("#ajaxform").submit(function() {
$("#hidden_message").val($("#message_body").val());
return true;
});
}
You can add a hidden field body in your ajax form, and use an onsubmit event to populate it with the value of the body field from the normal form before the ajax request is sent. It would look more or less like this:
<%= form_for #message do |f| %>
<%= f.text_field :to %>
<%= f.text_area :body, :class => 'main_body_field' %>
<%= f.submit "Send Message" %>
<% end %>
<%= form_for :save, :url => save_message_path(), :remote => :true, :id => 'ajax_form' %>
<%= f.hidden_field :body, :class => 'hidden_body_field' %>
<%= f.submit "Save" %>
<% end %>
javascript (with jQuery):
$(function() {
$("ajax_form").submit(function() {
// copy body value from first form to the second one
$('.hidden_body_field').val($('.main_body_field').val());
return true;
}
}