Rails Simple Form :first :last - ruby-on-rails

Writing a fairly long form using the simple form gem but having trouble with the radio button collections. Users are asked questions and have radio buttons to choose from but the value to be entered is different than what is being displayed for the user. Here is an example line of my code,
<%= f.collection_radio_buttons :shower_flow_rate, prompt: "Do you have low flow shower heads?",[[2.5, 'Yes'] ,[3.8, 'Some'], [5.0, 'No']], :first, :last%>
:shower_flow_rate is the variable I want filled. What are :first and :last? Are they necessary? I found very little documentation explaining the :first and :last.
Also I have several attributes in the same schema that need to be filled by calculating the sum or product of some of these inputs in the form. Should these values be calculated in the view or in the controller?

In you case yes they are necessary, first & last are array methods. (You can use any methods instead of :first, :last which is valid for the each element of the collection)
Ref collection_radio_buttons
In you case following is collection
[[2.5, 'Yes'] ,[3.8, 'Some'], [5.0, 'No']]
So, :first & :last are the methods which will call on each
element of the collection to create an HTML
# For Ex:-
# [2.5, 'Yes'].first => 2.5
# [2.5, 'Yes'].last => 'Yes'

Related

How to set the value of a string field using a checkbox?

In a Rails app I have a model with a string attribute, that can only accept a short list of possible values.
A gender select is a good example of this:
(using simpleform)
<%= f.input :gender, :collection => [["male"],["female"]], :prompt => "Select" %>
and provides three states, 'male', 'female', and unselected.
In an effort to improve UX, we're replacing this select field with two checkboxes with values of 'male' and 'female', which again provides three options due to some jquery magic.
male / false
false / female
false / false
The problem is, the value of the first checkbox is alway overwritten by the value of the second on form submit.
Now I could do something with jquery on the client side to deal with this, I could also create a method on the server to deal with this. But that is not the purpose of this question.
I've never been confident that I fully understand all of the various features and uses of f.check_box, check_box object and check_box_tag. Is there a clever way to achieve the desired result within a Rails form, or am I on the wrong track?

Rails - Tagging with has_many through and select2

I'm implementing select2 tagging with a has_many through relationship. My implementation has 2 different scenarios.
The select menu allows multiple (tagging) but does not allow on the fly input into the select menu.
Same as above but uses ajax to allow the user to enter new select values on the fly.
Scenario 1 works well for tagging. Scenario 2 seems to work (can perform tagging) but does not save the values. My problem seems to come down to my my input elements for the scenarios.
Scenario 1 uses:
<%= f.association :repairers, label_method: :rep_name, value_method: :id, include_blank: true, label: 'Repairer'%>
and when the form is submitted gives params similar to:
"repairer_ids"=>["", "1132", "1131"]
Scenario 2 uses:
<%= f.hidden_field :repair_type_id, :class => "required on-the-fly-select select"%>
and uses a lot of js code to implement on the fly input for the select menu. When the form is submitted the data will look like:
"repair_type_id"=>"5688,5690"
So with scenario 2 the ids are not submitted as an array. I have tried changing the select to:
<%= hidden_field_tag("repair_item[repair_type_ids][]", "", :id => "repair_item_repair_type_ids", :class => "required on-the-fly-select select") %>
but then the relevant param is submitted incorrectly and doesn't save:
"repair_type_ids"=>["5688,5690"]
Is it possible to get the params from Scenario 2 to submit in the format that Rails made the params in Scenario 1?
Try String#split
repair_type_id = "5688,5690"
repair_type_id.split(',')
=> ["5688", "5690"]
It's Better to use this split method in controller while saving the data on particular attribute for this instead of on hidden_tag.
Edit:
If you want to convert string in plural then use pluralize same as for singularize
2.0.0-p481 :010 > 'cat'.pluralize
=> "cats"
2.0.0-p481 :011 > 'dogs'.singularize
=> "dog"

Wrong number of arguments (2 for 4) using simple_form checkboxes

I'm a little confused by the read me for simple_form in regards to a collection of check boxes. Namely, what else am I expected to put on the line besides my options. The readme has :first, :last but doesn't really explain what purpose those words server.
Below are two different collections of checkboxes I'd like to have. I should also mention, each checkbox relates to a boolean field in the DB and they are labeled the same as the column names.
<%= f.collection_check_boxes :options, [[false, 'App'], [false, 'DB'], [false, 'WCF']] %>
<%= f.collection_check_boxes :options, [[false, 'Com1'], [false, 'Com2'], [false, 'BofA']] %>
I forgot to mention, the error I'm getting when I try to load this page is
wrong number of arguments (2 for 4)
This error simply mean that your <%= f.collection_checkboxes %> takes 2 arguments but your giving it 4. Remember this for future reference as this mistake can be easily made.
Right from this example below:
form_for #user do |f|
f.collection_check_boxes(
:options, [[true, 'Yes'] ,[false, 'No']], :first, :last
) do |b|
b.label { b.check_box + b.text }
end
end
The rubydoc.info website states the following:
It is also possible to give a block that should generate the check box + label. To wrap the check box with the label, for instance as above:
So from my understanding of this the :first and :last represent the labels as it were. So that you'd have two check boxes. That are either true or false but then outside that option array you are providing the label those instances of the class. So lets take this example. That is providing the label the instances :first and :last of the class User. Hope this clarifies things. The link is provided below:
Ruby Doc- SimpleForm collection_check_boxes

Can someone explain collection_select to me in clear, simple terms?

I am going through the Rails API docs for collection_select and they are god-awful.
The heading is this:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
And this is the only sample code they give:
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, :prompt => true)
Can someone explain, using a simple association (say a User has_many Plans, and a Plan belongs to a User), what I want to use in the syntax and why?
Edit 1: Also, it would be awesome if you explained how it works inside a form_helper or a regular form. Imagine you are explaining this to a web developer that understands web development, but is 'relatively new' to Rails. How would you explain it?
collection_select(
:post, # field namespace
:author_id, # field name
# result of these two params will be: <select name="post[author_id]">...
# then you should specify some collection or array of rows.
# It can be Author.where(..).order(..) or something like that.
# In your example it is:
Author.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name_with_initial, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# <option value=#{author.id}>#{author.name_with_initial}</option>
# 'author' is an element in the collection or array
:prompt => true # then you can specify some params. You can find them in the docs.
)
Or your example can be represented as the following code:
<select name="post[author_id]">
<% Author.all.each do |author| %>
<option value="<%= author.id %>"><%= author.name_with_initial %></option>
<% end %>
</select>
This isn't documented in the FormBuilder, but in the FormOptionsHelper
I've spent quite some time on the permutations of the select tags myself.
collection_select builds a select tag from a collection of objects. Keeping this in mind,
object : Name of the object. This is used to generate the name of the tag, and is used to generate the selected value. This can be an actual object, or a symbol - in the latter case, the instance variable of that name is looked for in the binding of the ActionController (that is, :post looks for an instance var called #post in your controller.)
method : Name of the method. This is used to generate the name of the tag.. In other words, the attribute of the object you are trying to get from the select
collection : The collection of objects
value_method : For each object in the collection, this method is used for value
text_method : For each object in the collection, this method is used for display text
Optional Parameters:
options : Options that you can pass. These are documented here, under the heading Options.
html_options : Whatever is passed here, is simply added to the generated html tag. If you want to supply a class, id, or any other attribute, it goes here.
Your association could be written as:
collection_select(:user, :plan_ids, Plan.all, :id, :name, {:prompt => true, :multiple=>true })
With regards to using form_for, again in very simple terms, for all tags that come within the form_for, eg. f.text_field, you dont need to supply the first (object) parameter. This is taken from the form_for syntax.

simple_form input with multiple fields

I'm not quite sure what the correct terms are, but what I'm trying to do is in a form (preferably using the simple_form gem) have one of the inputs, :maximum, use both a text field and select box. The user would type in the text box a number, and then select from a dropdown box of hours, days, or months. So 21 days, 3 months, 3 hours, etc. When the form was submitted I would convert that to days and store it in the database. I know how to change the input type in simple_form, but is it possible to have two inputs for one variable?
Sure :) Here is my idea:
First, you define accessors in your user model:
attr_accessor :thing, :another_thing, :and_another_thing
Then in your view, 'inside' form_for helper, you could write for example:
<%= form.input :thing, :as => :boolean %>
<%= form.input :another_thing, :as => :text %>
...or whatever you want. (Note: I am using formtastic here. You should consider using Rails methods if you're not using formtastic gem. )
Finally, you define a callback in you user model:
before_create :build_my_fancy_record
def build_my_fancy_record
self.storage_field = "#{thing} #{another_thing}"
end

Resources