如何为collection_select追加属性并自定义选项显示内容?
Hey there! Glad you asked—this is a common form customization in Rails, and there are two straightforward, clean ways to make your collection_select show the combined name and third_party boolean value.
Option 1: Use a Lambda Directly in the View
If you only need this specific formatting in one place, you can replace the :name label method with a lambda that constructs the display text on the fly:
<div class='form-group'> <%= f.label :project_component_id, class: 'form-label' %> <%= f.collection_select :project_component_id, issue.project.project_components.order('LOWER(name)'), :id, # Lambda to combine name and third_party status ->(component) { "#{component.name}(#{component.third_party})" }, {include_blank:true}, class: 'form-control input-sm' %> </div>
If you want friendlier text instead of raw true/false (like "Third Party" or "Internal"), tweak the lambda like this:
->(component) { "#{component.name}(#{component.third_party ? 'Third Party' : 'Internal'})" }
Option 2: Add a Helper Method to Your Model
For better reusability (if you need this formatted name in multiple views or contexts), define a dedicated method in your ProjectComponent model:
# app/models/project_component.rb class ProjectComponent < ApplicationRecord # ... your existing model code ... def display_name # Basic version with raw boolean value "#{name}(#{third_party})" # Or the user-friendly version # "#{name}(#{third_party ? 'Third Party' : 'Internal'})" end end
Then update your collection_select to reference this new method:
<div class='form-group'> <%= f.label :project_component_id, class: 'form-label' %> <%= f.collection_select :project_component_id, issue.project.project_components.order('LOWER(name)'), :id, :display_name, {include_blank:true}, class: 'form-control input-sm' %> </div>
This approach keeps your view code clean and centralizes the formatting logic, making it easier to update later if you change how you want to display the third-party status.
内容的提问来源于stack exchange,提问作者Shnarf

