Generate parameters in ruby on rails - ruby-on-rails

I want an update method in the controller to get parameters in a specific format. The current format by which I am getting the parameters is
Parameters: {"utf8"=>"✓", "authenticity_token"=>"temp", "performance_areas"=>{"0"=>{"performance_area"=>"New item"}, "1"=>{"performance_area"=>"Delete Item"}, "commit"=>"Submit"}
This is being generated as a name in my text field with 0 and 1 indicating the areas index. I want some additional parameters in this in the following format:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"temp", "performance_areas"=>{"0"=>{id: 1, description: "This is a test","performance_area"=>"New item"}, "1"=>{id: 2, description: "This is a test2","performance_area"=>"Delete Item"}, "commit"=>"Submit"}
Any pointers how to get the parameters in the way I want. I do have performance_areas that has the id and description in it. Do let me know if any further clarification is required.
EDIT: Form code (just pasting the critical section of the long code)
<%= form_tag({:performance => :update}, :method => :put) do %>
<% #performance_areas.each_with_index do |performance_area, i| %>
<%= hidden_field_tag :performance_area, performance_area, :name => "performance_areas[#{i}][performance_area]" %>
<%= submit_tag %>

I think you want this, I am assuming that both id and description are in performance_area object
<%= form_tag({:performance => :update}, :method => :put) do %>
<% #performance_areas.each_with_index do |performance_area, i| %>
<%= hidden_field_tag :id, performance_area.id, :name => "performance_areas[#{i}][id]" %>
<%= hidden_field_tag :description, performance_area.description, :name => "performance_areas[#{i}][description]" %>
<%= hidden_field_tag :performance_area, performance_area, :name => "performance_areas[#{i}][performance_area]" %>
<%= submit_tag %>
<% end %>

Related

select_tag to choose which param to pass as true into the query string

I have the following code:
<%= form_tag users_path, method: :get do %>
<%= check_box_tag 'popularity', true %>
<%= submit_tag "Search", :name = "nil", :id => "submit" %>
<% end %
when selected it results in:
www.example.com/users?popularity=true
However, because I have multiple order scopes, what I want to do is to create a select_tag with a dropdown, where the Use can choose between popularity, photos_count and recent_activity and
his single choice will be passed into the query string as such:
example.com/users?popularity=true
or
example.com/users?photos_count=true
or
example.com/users?recent_activity=true
There is not actually a :sort_type column in my user database. I am just using enum as a way of organizing the scopes so that one of them can be passed into the query string.
<%= form_tag users_path, method: :get do %>
<%= select_tag :sort_type, options_for_select(User.sort_types, :selected => params[:sort_type]), :include_blank => true %>
<% end %>
class User
enum sort_type: ["popularity", "number of photos"]
end
I then use the controller to set the scope based on the params[:sort_type] integer that was passed into the query string from the form.

Rails AssociationTypeMismatch on object sent by a check_box_tag inside a form_for

Rails is getting me this error Subject(#70287575068140) expected, got String(#70287576459120), but my parameters are:
Parameters:
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"rISZVyQZgcLCGP1y7F4qg7xmW1miuaJvwUe5gu59/MqjjSWem/3JzCei5EPuZSSVdZyqO8bq0eRk0w9zCo0mDA==",
"student"=>{"name"=>"Eduardo Pedroso",
"rg"=>"39468291-0",
"phone"=>"981713271",
"address"=>"Rua dr Camilo marques",
"birthday"=>"2015-06-08",
"scholarity"=>"Superior",
"responsible_id"=>"1",
"subjects"=>["#<Subject:0x007fda346828e0>",
"#<Subject:0x007fda34682660>"]},
"commit"=>"Edit student",
"id"=>"1"}
And the checkbox that sends the subjects params
<% Subject.all.each do |subject| %>
<%= check_box_tag :subjects_id, subject, #student.subjects.include?(subject), :name => 'student[subjects][]' -%>
<%= label_tag :subjects, subject.name %>
<% end %>
Try changing
<%= check_box_tag :subjects_id, subject, #student.subjects.include?(subject), :name => 'student[subjects][]' -%>
to
<%= check_box_tag :subjects_id, subject, #student.subjects.include?(subject), :name => 'student[subjects_id][]' -%>
You better check the definitions around the check_box_tag helper
It goes like this:
check_box_tag(name, value = "1", checked = false, options = {})
So comparing with your use, you have assigned the name attribute twice and assigned as value the object subject.
I believe you intended to assign the subject.id as value, so you can fix it by replacing the check_box_tag call as:
<%= check_box_tag 'student[subjects][]', subject.id, #student.subjects.include?(subject) -%>

Rails check_box_tag within form_for

Is it possible to pass the value of checked check_box_tags within a form_for in Rails inside a hash?
Here is a very generic, basic version of the form:
<%= form_for(:object, :url => { :action => 'create', :id => params[:id]}) do |f| %>
<p>Field_a: <%= f.text_field(:field_a) %></p>
<p>Field_b: <%= f.text_field(:field_b) %></p>
<p>Field_c: <%= f.text_field(:field_c) %></p>
<p>Check boxes:</p>
<% check_box_choices_object_array.each do |s| %>
<%= check_box_tag(s.name, 1, false) %>
<%= .name %><br />
<% end %>
<%= submit_tag("Create") %>
<% end %>
Outputs roughly:
Field_a ___________________
Field_b ___________________
Field_c ___________________
Check boxes:
[] box_a
[] box_b
[] box_c
[] box_d
[] box_e
[] box_f
[] box_g
My problem is that since the available check boxes aren't actual fields in the object's table in the database (i.e. I'm not using check_box(:field) in the form), each checked check box gets passed as an individual parameter (i.e. "box_a" => "1", "box_b" => "1", "box_e" => "1"). I would like them to be passed as such:
:checked_boxes => {"box_a" => "1", "box_b" => "1", "box_e" => "1"}
This way, I can access them easily with params[:checked_boxes].
How do I do this, or, better yet, is there a better solution (I'm new to rails)?
I think you'd get the results you want if you wrap the checkboxes iterator in a fields_for :checked_boxes tag - or at least get you close to the results you want.
<%= form_for(:object, :url => { :action => 'create', :id => params[:id]}) do |f| %>
<p>Field_a: <%= f.text_field(:field_a) %></p>
<p>Field_b: <%= f.text_field(:field_b) %></p>
<p>Field_c: <%= f.text_field(:field_c) %></p>
<p>Check boxes:</p>
<%= f.fields_for :checked_boxes do |cb| %>
<% check_box_choices_object_array.each do |s| %>
<%= cb.check_box(s.name, 1, false) %>
<%= .name %><br />
<% end %>
<% end %>
<%= submit_tag("Create") %>
<% end %>
you can deal with no database attributes and models using attr_accessor
class Thing < ActiveRecord::Base
attr_accessible :name
attr_accessor :box_a, :box_b, :box_c
end
This way you can call these attributes in your form.

Rails - creating multiple records, not all params are being passed

I'm trying to add multiple product skus to an order at once.
Product has_many skus,
Order has_many order_lines
So in my order, I pull up a product and see all its skus (brown-small, brown-large) I then enter the qty of each I want to put on the order.
For some reason, it is only passing the :qty_sold params, and not the :sku_id - any reason why?
Routes:
post '/order_lines/create' => 'order_lines#create', :as => :create_order_lines
Form:
<%= form_tag create_order_lines_path do %>
<%= hidden_field_tag :order_id, #order.id %>
<% #product.first.skus.each_with_index do |sku, index| %>
<%= text_field_tag "order_lines[#{index}]", :sku_id, {:value => sku.id } %>
<%= sku.colour %>
<%= text_field_tag "order_lines[#{index}]", :qty_sold, {:value => ''} %>
<% end %>
<%= submit_tag "Add" %>
<% end %>
Output:
Started POST "/order_lines/create" for 127.0.0.1 at Fri Mar 16 23:13:27 -0400 2012
Processing by OrderLinesController#create as HTML
Parameters: {"commit"=>"Add", "order_id"=>"1", "authenticity_token"=>"JmImxbFUGLdM6Vt0rrS9RabSCUi1kV2QRTpWp34BBb4=", "utf8"=>"\342\234\223", "order_lines"=>{"0"=>"7", "1"=>"8", "2"=>"", "3"=>"9", "4"=>"", "5"=>""}}
This line is setting the key that you're having problems with
text_field_tag "order_lines[#{index}]"
So basically you're saying order_lines[X] = and since :qty_sold is the last option set to that key it's getting assigned that value.
To accomplish what you're trying to accomplish you would need to go a level deeper, like this
<%= text_field_tag "order_lines[#{index}][qty_sold]", :qty_sold, {:value => ''} %>
Honestly though, you should consider looking into the fields_for helper it does everything you want to accomplish and is more abstract.
This is untested but I think it should work
<% #product.skus.each do |sku| %>
<%= fields_for :order_lines do |order_line_fields| %>
<%= order_line_fields.text_field :sku_id, {:value => sku.id} %>
<%= sku.colour %>
<%= order_line_fields.text_field :qty_sold %>
<% end %>
<% end %>

Get an array from a Rails form

I need to design a form for a account resource. In that form, i need to collect some set of ids as an array in the params hash in attribute called relationships.
So the final params[account] hash from the POST request should be like:
{:name => 'somename', :relationships => ["123", "23", "23445"]}
How shall I design the form_for fields? I tried this, but didn't work:
<%= form_for #account do |f| %>
<%= f.text_field :name %>
<% #eligible_parents.each do |p| %>
<%= f.check_box "relationships", nil, :value => p.id %>
<b><%= p.name %></b><br/>
</span>
<% end %>
<%= f.submit "Submit" %>
<% end %>
Number of elements in #eligible_parents varies every time.
relationships is neither an association nor an attribute in account model.
I have to use virtual attributes but I need to fill in an array from a form.
Please help. How can I do this?
You still need a fields_for in your view, just use :relationships as the record_name then provide an object.
<%= form_for #account do |f| %>
<%= f.text_field :name %>
<% fields_for :relationships, #eligible_parents do |p| %>
<%= p.check_box "relationships", nil, :value => p.object.id %>
<b><%= p.object.name %></b><br/>
<% end %>
<%= f.submit "Submit" %>
<% end %>
Documentation here: ActionView::Helpers::FormHelper
I found this to be the cleanest way...
If you are working with straight data and want to send back an array without using any of these #objects:
<%= form_for :team do |t| %>
<%= t.fields_for 'people[]', [] do |p| %>
First Name: <%= p.text_field :first_name %>
Last Name: <%= p.text_field :last_name %>
<% end %>
<% end %>
your params data should return like this:
"team" => {
"people" => [
{"first_name" => "Michael", "last_name" => "Jordan"},
{"first_name" => "Steve", "last_name" => "Jobs"},
{"first_name" => "Barack", "last_name" => "Obama"}
]
}
If you want to send array of values just use [] in name attributes.In your case just use
<%= f.check_box "relationships", {}, :value => p.id, :name => "relationships[]" %>
In a complex form, with nested attributes, you can make use of the f.object_name helper. But beware of the syntax when doing interpolation. This is correct:
"#{f.object_name}[relationships][]"
This is NOT correct:
"#{f.object_name}[relationships[]]"
It always trips me up.
I'm working in something similar. My issue was how to pass the input name to a partial to resolve it as a hash using the rails form_for helper.
So, my solutions was something like this:
= render 'my_partial', form: form, name: "item_ids[item.id]"
So, this gonna render an html like this:
<input class="form-control" name="products[items_ids[1]]" id="products_items_ids[1]">
The number 1 is the item.id, this is how HTML understand that you gonna pass an array or hash, all depends your config.
So, the params gonna look like this:
"items_ids"=>{"1"=>"1"}
This is working for me with an form_object + virtus

Resources