From a3a42f65e256cc8aec5e0dcba5cd2936bb4ef83a Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Fri, 5 Aug 2022 16:17:15 -0500 Subject: [PATCH] Mention associations in Form Helpers guide [ci-skip] This fleshes out the "Choices from a Collection of Complex Objects" section a bit more, explicitly mentioning associations and proper field naming. --- guides/source/form_helpers.md | 72 +++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md index 7ad43eb4bfba2..8626aa8be7e9e 100644 --- a/guides/source/form_helpers.md +++ b/guides/source/form_helpers.md @@ -584,22 +584,37 @@ For each of these helpers, you may specify a date or time object instead of a nu Choices from a Collection of Arbitrary Objects ---------------------------------------------- -Often, we want to generate a set of choices in a form from a collection of objects. For example, when we want the user to choose from cities in our database, and we have a `City` model like: +Sometimes, we want to generate a set of choices from a collection of arbitrary objects. For example, if we have a `City` model and corresponding `belongs_to :city` association: ```ruby -City.order(:name).to_a -# => [ -# #, -# #, -# # -# ] +class City < ApplicationRecord +end + +class Person < ApplicationRecord + belongs_to :city +end +``` + +```ruby +City.order(:name).map { |city| [city.name, city.id] } +# => [["Berlin", 3], ["Chicago", 1], ["Madrid", 2]] ``` -Rails provides helpers that generate choices from a collection without having to explicitly iterate over it. These helpers determine the value and text label of each choice by calling specified methods on each object in the collection. +Then we can allow the user to choose a city from the database with the following form: + +```erb +<%= form_with model: @person do |form| %> + <%= form.select :city_id, City.order(:name).map { |city| [city.name, city.id] } %> +<% end %> +``` + +NOTE: When rendering a field for a `belongs_to` association, you must specify the name of the foreign key (`city_id` in the above example), rather than the name of the association itself. + +However, Rails provides helpers that generate choices from a collection without having to explicitly iterate over it. These helpers determine the value and text label of each choice by calling specified methods on each object in the collection. ### The `collection_select` Helper -To generate a select box for our cities, we can use [`collection_select`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_select): +To generate a select box, we can use [`collection_select`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_select): ```erb <%= form.collection_select :city_id, City.order(:name), :id, :name %> @@ -608,7 +623,7 @@ To generate a select box for our cities, we can use [`collection_select`](https: Output: ```html - @@ -619,7 +634,7 @@ NOTE: With `collection_select` we specify the value method first (`:id` in the e ### The `collection_radio_buttons` Helper -To generate a set of radio buttons for our cities, we can use [`collection_radio_buttons`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_radio_buttons): +To generate a set of radio buttons, we can use [`collection_radio_buttons`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_radio_buttons): ```erb <%= form.collection_radio_buttons :city_id, City.order(:name), :id, :name %> @@ -628,31 +643,38 @@ To generate a set of radio buttons for our cities, we can use [`collection_radio Output: ```html - - - - - - + + + + + + + + ``` ### The `collection_check_boxes` Helper -To generate a set of check boxes for our cities (which allows users to choose more than one), we can use [`collection_check_boxes`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_check_boxes): +To generate a set of check boxes — for example, to support a `has_and_belongs_to_many` association — we can use [`collection_check_boxes`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_check_boxes): ```erb -<%= form.collection_check_boxes :city_id, City.order(:name), :id, :name %> +<%= form.collection_check_boxes :interest_ids, Interest.order(:name), :id, :name %> ``` Output: ```html - - - - - - + + + + + + + + + + + ``` Uploading Files