Custom display label for grouped_collection_select - ruby-on-rails

I have the following grouped_collection_select in my View:
<%= grouped_collection_select(:classroom, :course_id, #classrooms, :courses, :name, :id, :name) %>
How do I customize the display label such that it is the concatenation of 2 attributes?

grouped_collection_select takes a method-name as the parameter for the label. Labels are generated by calling that method on each object in the collection.
In your example, the method is called :name but you could create a method on your Classroom class that contains the two attributes you want eg:
# totally made up - use whatever attributes and method-name you want
def name_and_location
[name, location].join(': ')
end
then just use it in the collection-select:
<%= grouped_collection_select(:classroom, :course_id, #classrooms, :courses, :name_and_location, :id, :name) %>
Note: the above example is for the group-label... hut you can equally well do the same for the individual item-label, just use the last parameter and put the method on your Course model instead.

Related

Rails grouped_collection_select value_method with parameters

Is there any way to use grouped_collection_select value_method with parameters in Rails?
I'm trying to filter out a couple of options based on the current_user (effectively using something like: signed_by(current_user)) but I'm having some difficulty passing it in.
<%= f.grouped_collection_select :author_id, Author.posts, :signed_by, :title, :id, :email %>
Any ideas?
It's not possible to pass parameters to the value_method in this case because the value_method option is "the name of a method which, when called on a child object of a member of collection, returns a value to be used as the contents of its tag". In other words, it's just a string or symbol that will get called on the Author.posts collection.
If you're trying to filter out some options, I would suggest filtering them from the collection, and then passing the filtered collection to this method. Something like:
# author_helper.rb
def filtered_author_posts
Author.posts.where.not(signed_by: current_user)
end
<%= f.grouped_collection_select :author_id, filtered_author_posts, :signed_by, :title, :id, :email %>

Simple Form - Multiple attributes in checkbox group

I have a User Model with the following attributes:
# full_time :boolean
# part_time :boolean
# contract :boolean
I would like to create a simple form checkboxes group for these attributes. From what I've been able to understand, the simple form api is meant to map to has_many & has_and_belongs_to_many associations, as follows:
f.collection_check_boxes :role_ids, Role.all, :id, :name
Is there a way to handle updating multiple attributes on the given model within the form's API guidelines? Or is this an indication that should I be modeling the data in a different way?
f.collection_check_boxes is a generic method for generating multiple checkboxes with arbitrary name/value, for a single attribute. The sample you gave is mentioned in the docs as a last one for this method, probably because f.association is way better for association attributes.
<%= f.association :role, Role.all %>
In case of your attributes, I don't think f.collection_check_boxes is applicable. If the attributes aren't mutually exclusive, then I don't see anything wrong - stick with them and just give each one a checkbox of it's own.
<%= f.input :full_time %>
<%= f.input :part_time %>
<%= f.input :contract %>
simple_form will detect their type and generate a checkbox for each. Use wrapper: false option, if you want to get rid of wrapper divs and group them more tightly.
If they were mutually exlusive, then an integer column and enum would be probably a better idea.

How to default collection_check_boxes to checked?

I have this line that I'm trying to default to checked <%= f.collection_check_boxes :committed, checked, Date::ABBR_DAYNAMES, :downcase, :to_s, %>
In db t.text "committed".
I tried variations of checked & true, but maybe I overlooked something.
Here's the Gist of it.
Here is a quick answer on how to add checked as the default to the collection_check_boxes form helper since it took me some time to figure it out. Break it into a block and you can set checked and add classes. More info at http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes.
<%= f.collection_check_boxes(:author_ids, Author.all, :id, :name) do |b| %>
<%= b.label(class: "check_box") { b.check_box(checked: true, class: "add_margin") + b.text } %>
<% end %>
You are using a form_for, so that f is a form builder. This means that it is bound to the object you initialized it with, let's call it #habit. Since you're calling collection_check_boxes on the form builder, it will do something like #habit.send(:commit) to consult whether or not it should have the check box checked, and currently (apparently) it is not. In other words, if you want to use form_for you need to have this "everything is checked" fact represented in the model itself.
Now I am not sure what your model layer looks like, so I'll address a few scenarios. If you have a has_and_belongs_to_many relationship like this:
class Habit < ActiveRecord::Base
has_and_belongs_to_many :committed_days
end
class CommittedDay < ActiveRecord::Base
has_and_belongs_to_many :habits
# let's assume it has the columns :id and :name
# also, let's assume the n:m table committed_days_habits exists
end
Then I think the easiest way is in the controller itself do something like this:
def new
#habit = Habit.new
#habit.committed_day_ids = CommittedDay.all.map(&:id)
end
And in your ERB do:
<%= f.collection_check_boxes(:committed_day_ids, CommittedDay.all, :id, :name)
Now, it might be an overkill to do this with a has-and-belongs-to-many, especially with days of week (it means the CommittedDay table has 7 records, one for each day, which is kinda awkward). So you could also consider simply serializing an array of days of week into the db, and then just make sure the default for that column contains all of them.
The ERB will be similar to what you wrote:
<%= f.collection_check_boxes :committed, Date::ABBR_DAYNAMES, :downcase, :to_s %>
If you're using Postgres your class can be simply:
class Habit < ActiveRecord::Base
end
And the serialization code would be in the migration:
# downcase is used since in the ERB you are using :downcase for the id method
t.text :committed, default: Date::ABBR_DAYNAMES.map(&:downcase), array: true
If you are not using Postgres, you can use Rails serialization which is DB agnostic:
class Habit < ActiveRecord::Base
serialize :committed, Array
end
And then your migration would look like this:
t.text :committed, default: Date::ABBR_DAYNAMES.map(&:downcase).to_yaml

How to use collection_select in rails 4 from a model module?

I am trying to use collection_select tag for the default _form.html.erb using a concern/module, I need to set a hash including some department names.
Here is my app/models/concerns/SetDepartment.rb
module Set_Department
extend ActiveSupport :: Concern
def department
department {
1=>"Amatitlán",
2=>"Chinautla",
3=>"Chuarrancho"
}
end
end
Here is the model where I want to call the department method:
class Aplicante < ActiveRecord::Base
include SetDepartment
validates :titulo_id, :primer_nombre,
:primer_apellido, :dpi, :direccion_linea_1,:zona, :department_id, :username,
presence: true
validates :dpi,:username, uniqueness: true
has_secure_password
end
Now, I need to include this hash in a collection_select tag on my app/views/applicants/_form.html.erb
#...
<div class="field">
<%= f.label :department_id %><br>
<%= f.collection_select :department_id, Aplicante.department, Aplicante.department %>
</div>
#...
Obviously, this does not work but I can not think on anything else.
I have searched through the internet but I just get tough explinations and none of them involves a module... is it even possible?
Solved!
I was using the wrong method..
We can not use a collection_select helper with a hash, instead, we need to use the regular select method.
Collection_select is used when you have two models and you want to combine their different values in a drop down menu.
Information about how to use the select tag with a hash here:
http://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag

ruby on rails how to use FormOptionHelpers to create dynamic drop down list

I have checked some tutorials but I got confused by the parameters in this method
collection_select (object, attribute, collection, value_method, text_method, options = {}, html_options ={})
I have a map model includes: :area, :system, :file
and I want to read :area from database to a drop down list, and let user choose one
I already did #map = Map.all in the view
what the method should be?
especially the parameter "attribute". In a lot tutorials, people put "id" here. But I don't know what "id" is, and in my situation I don't need any other value, just the "area".
Im not exactly sure what you are asking here but if you are trying to make a dropdown selection for use in an html form will this example help you at all?
<% nations = {'United States of America' => 'USA', 'Canada' => 'Canada', 'Mexico' => 'Mexico', 'United Kingdom'=> 'UK'} %>
<% list = nations.sort %>
<%= f.select :country, list, %>
Here nations is a hash of countries then list becomes the sorted copy of that hash. An html dropdown is then created as a part of the form "f". ":country" is the part of the model that the data is connected to while list is the options to populate the dropdown with
It's not clear from your question what the model is that's being populated with the area.
Typically, collection_select is used between related models.
eg.
class Category < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :category
end
When selecting the 'category' for a product, your view would have something like:
<%= f.collection_select(:category_id, :id, Category.all, :name, include_blank: true) %>
What this does is specify the Product.category_id as the attribute being populated with the value of Category.id. The values come from the Category.all collection, and with Category.name being the item displayed in the select. The last (optional) parameter says to include a blank entry.
Something like the following is probably what you need:
<%= f.collection_select(:map_id, :id, #map, :area) %>
However, if the model you're trying to populate has an area attribute (instead of an ID linking to the map), you might need to use:
<%= f.collection_select(:area, :area, #map, :area) %>
This specifies that the area attribute of the receiving table will be populated with Map's area attribute, which is also being used as the "description" in the select.

Resources