Translating form_for syntax to simple_form syntax - ruby-on-rails

I have this code within my rails form:
Categories: <%= f.collection_select :tag_ids, Tag.order(:name), :id, :name, {}, {multiple: true} %>
This code is working, but I want to use simpleform gem to redesign my form. However, I cannot seem to figure how to 'translate' this code into simple form. Anyone have any idea how? Thanks.

Something like this should do the trick:
If you have a many to many relation you could first try what the default does.
<%= f.association :tags %>
If the defaults don't work out you can make an explicit collection:
<%= f.input :tag_ids, as: :select, collection: Tag.order(:name), label_method: :name, input_html: {multiple: true} %>
# or
<%= f.input :tag_ids, as: :select, collection: Tag.order(:name).pluck(:name, :id), input_html: {multiple: true} %>
Alternatively if you define the Tag#to_label method you don't have to pass the name of the label method. The Tag#id gets used as default value method. If you would like another value specify the method like so: value_method: :something_else.
See the simple_form Usage section (intro, collections and associations).

Related

Simple form hidden association

This is weird behavior.
I have this as part of a form:
<%= f.association :blog, collection: current_user.blogs, selected: #blog %>
This works. However, as soon as I add this extra attribute:
<%= f.association :blog, collection: current_user.blogs, selected: #blog, as: :hidden %>
I get a validation error saying that my model needs a blog to be associated with it. It seems that adding as: :hidden to it makes it lose the value.
Any ideas?
It does not need to be select, because it's hidden field. I think the following code will solve the problem:
<%= f.input :blog_id, as: :hidden, input_html: { value: #blog.id } %>

SimpleForm (Can you set default label_method and value_method parameters?)

Using SimpleForm, Can I set the default values for :label_method and :value_method so I do not need to set it for each input?
By default, I mean a place to set label_method and value_method for all my inputs, so I do not need to set them for each input.
Example:
Instead of this:
<%= f.association :model_in_question, include_blank: false, label_method: :label_for_form, value_method: :value_for_form %>
I want this:
<%= f.association :model_in_question, include_blank: false %>
I think this is what you're looking for:
Simple form association custom label name
<%= f.association :owner_type, :include_blank => false, :label_method => lambda { |owner| "#{owner.name} | #{owner.subtype_name}" } %>
The same logic applies for value_method. So if you have a model, you can make a method called label_for_form and value_for_form which return your required values. Then in your form:
<%= f.association :model_in_question, include_blank: false, label_method: :label_for_form, value_method: :value_for_form %>
So long as the objects in your collection respond to both those methods, then you won't need to manually write out the collection in the form.

Rails: Default Value - select field

I want to display a default select value. What I have so far is:
<%= f.collection_select(:user_id, User.where(brand: current_user.brand), :id, :name, {prompt:true}, {class: 'form-control'}, :selected => current_user.brand) %>
But this produces an error:
wrong number of arguments (7 for 4..6)
Any ideas what the problem is?
This should do the trick:
<%= f.collection_select(:user_id, User.where(brand: current_user.brand), :id, :name, {prompt: true}, {class: 'form-control', selected: current_user.brand}) %>
selected should be in the html_options. See also:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select

Rails form dropdown using two text_method

I am creating a form has a drop down selection. I want to use two "text_method"s for the input but I am unsure how to do this. I want to include the year and name (both are two different columns in my rails model.
Here is what I have but it does not work:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year, :model_name, include_blank: true %>
Here is the official documentation- http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
Use this in your view:
<%= f.collection_select :bat_id, Bat.all, :id, :model_year_and_name, include_blank: true %>
Add a method like this to your Bat model:
def model_year_and_name
"#{model_year} #{model_name}"
end

set data attribute in grouped_collection_select dynamically in rails 4

I have a form like this in my orders/new page. I have used this to select model location and then choose a model from the location according to what is selected in the above select box.
<%= f.label "SELECT MODEL LOCATION *" %>
<div class="list_number">1</div><%= f.collection_select :location_id, Location.all, :id, :formatted_display, prompt: true, :required => true, :class => 'chosen-select' %>
<%= f.label "SELECT YOUR MODEL *" %>
<div class="list_number">2</div>
<%= f.grouped_collection_select :performer_id, Location.order(:name).map{|group| Performer.find_by_location_id(group.id).map{|performer| {'data-markup'=>performer.white_label.markup}}}, :performers, :name, :id, :first_name, include_blank: true, :required => true, class: 'chosen-select' %>
In the grouped_collection_select when I use map to set the data attribute I am getting the following error:
undefined method `map' for #<Performer:0x00000006813958>
How do I solve this error and get the data required?
After trying the below code
<%= f.grouped_collection_select :performer_id, Location.order(:name).map{|group| Performer.where(location_id: group.id).map{|performer| {'data-markup'=>performer.white_label.markup}}}, :performers, :name, :id, :first_name, include_blank: true, :required => true, class: 'chosen-select' %>
I get the following error
undefined method `performers' for [{"data-markup"=>#<BigDecimal:67e80c8,'0.0',9(36)>}]:Array
When I tried the following
<%= f.grouped_collection_select :performer_id, Location.order(:name), :performers, :name, :id, :first_name,Location.order(:name).map{|group| Performer.where(location_id: group.id).map{|performer| {'data-markup'=>performer.white_label.markup}}}, include_blank: true, :required => true, class: 'chosen-select' %>
I get the following error
undefined method `merge' for #<Array:0x000000069705a8>
Performer.find_by_location_id(group.id)
returns an instance but map is method for Array.
The fix depends on your business logic (and APP structure)
You can use Performer.where(location_id: group.id).map... if there are many Performers
I think you try to use this helper wrongly. According to documentation you should pass a collection and group_method. group_method - The name of a method which, when called on a member of collection, returns an array of child objects representing the <option> tags.
You pass an array of objects [{'data-markup' => some_value}, ...] as collection and performers as group_method. Rails try to call {'data-markup' => some_value}.performers and this raises an exception.
You should rewrite a collection the following way:
1. it should be array
2. each item of array should have method performers - which return an array of objects under one group item
I hope it will help you
I can't test but it can work (if Location has_many performers or you can implement your own method according to your business logic)
<%= f.grouped_collection_select :performer_id, Location.order(:name), :performers, :name, :id, :first_name, include_blank: true, :required => true, class: 'chosen-select' %>

Resources