I'm working on learning Rails 4 via several tutorials, and building a demo app.
I have a table called players that links to a team table. The team has many players, a player has only one team. So I'm using a collection_select tag to pull the team data into the player form.
It looks like this:
<%= collection_select :player, :team_id, Team.find(:all), :id, :name, options ={:prompt => "Select a team"} %>
This works fine-- but I'd like to have the format look like "Team Name: Team City"-- I can't figure out how to concatenate the :name and :city values in the tag however. Is this possible?
Create a method in your Team model like the following one
def name_with_city
"#{name}: #{city}"
end
Then use it as below
<%= collection_select :player, :team_id, Team.find(:all), :id, :name_with_city, {:prompt => "Select a team"} %>
Find out more about collection_select in the documentation
You can format the collection to your liking as:
<%= collection_select :player,
:team_id,
Team.find(:all).collect { |t| [ t.id, "#{t.name}: #{t.city}" ] },
:first,
:last,
{ prompt: "Select a team" } %>
The :id and :name parameters have been replaced with first and last signifying the value_method to be first and text_method to be last elements of each array.
If your form is looking up values based on parameters and you need those, the model method is not very convenient. Assuming your controller has a #searched_record method, you can do something like
<% #base_params = #searched_record.one_value << "=>" << #searched_record.second_value << "; " << (l(#searched_record.starts, :format => :long)) << ", " << #searched_record.other_value.description %>
<%= f.text_area :content, :rows => 5, value: #base_params %>
Related
I'm building a form where users create a financial transaction. One field is a drop down list of bank accounts.
I would like this dropdown list to group all listed Bank Accounts by each account's account type (BankAccount::ACCOUNT_TYPE - an attribute in each BankAccount record).
If I manually code everything right now, the code would look like this:
<%= f.select :bank_account_id,
{
'On-Budget' => ['Cash',
'Credit Card 1',
'Credit Card 2',
'Venmo'],
'Off-Budget' => ['Investment Bank 1',
'Investment Bank 1'],
'Closed' => ['Old Bank 1',
'Old Bank 2'],
} %>
app/models/bank_account.rb - where I define ACCOUNT_TYPES
class BankAccount < ApplicationRecord
ACCOUNT_TYPES = %w(On-Budget Off-Budget Closed).freeze
...
end
Here is my working collection.select, without grouping
<%= f.collection_select :bank_account_id,
BankAccount.all,
:id,
:name,
{prompt: 'Select an account'} %>
From the rails API, I think grouped_collection_select is what I need
(https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-grouped_collection_select)
grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
Using BankAccount::ACCOUNT_TYPES as my group_method, and group_label_method doesn't work.
<%= f.grouped_collection_select(:bank_account_id,
BankAccount.all,
BankAccount::ACCOUNT_TYPES, (group_method?)
BankAccount::ACCOUNT_TYPEs, (group_label_method?)
:id,
:name,
{prompt: 'Select an account' } %>
I found the answer from this SO question: https://stackoverflow.com/questions/36854817/use-grouped-collection-select-to-group-a-model-by-enum
I created a helper method
def grouped_bank_account_options_for_select(selected_bank_account_id = nil)
options = {}
BankAccount::ACCOUNT_TYPES.each do |t|
unless t == "Closed"
options[t] = BankAccount.where(account_type: t)
.pluck(:name, :id)
end
end
grouped_options_for_select(options, selected_bank_account_id)
end
and then called it in the view's form helper
<%= select_tag :bank_account_id, grouped_bank_account_options_for_select(params[:bank_account_id]), {prompt: 'Select an account'} %>
How would one capitalise the first letter of a list of country's in below code example?
My question is regarding simple_form, not a regular form for which one could use collection_select.
= p.input :state,
:readonly => "readonly",
:collection => DataState.where(:country => "1"),
:selected => 1,
:id => "state",
:name => "state",
:prompt => "Please choose"
The problem is the list of states is in the database and saved like "alamaba","new york"
I need it to be down cased in the database but would like to uppercase/capitalize the first letter for visual clarity.
Try this:
In your DataState model, add a method that displays a capitalized version of your state names
class DataState < ActiveRecord::Base
def capitalized_state
state.capitalize
end
end
then use this new method to list your choices
Depending on if you're trying to save the id of the state as an association or just the string, the erb would be either
<%= f.input :state, collection: DataState.where(:country => "1").pluck(:capitalized_state) %>
or
<%= f.input :state, collection: DataState.where(:country => "1"), value_method: :id, label_method: :capitalized_state %>
where the former is for the state name and the latter is for the association id.
see this: using capitalize on a collection_select
Edit: I noticed that your html does not specify what attribute of the DataState class you're using as the text for your choices. If you're using rails, you should look into the collection_select form helper.
One way of going about it, too, would be the addition of the text-transform: uppercase property of css, looking like this:
<% = f.input: state, collection: DataState.where (: country => "1"), style: 'text-transform: uppercase;' %>
My form contains the following tag:
<%= f.collection_select :employee_id, #employees, :id, :value, :prompt => true %>
Employee looks like this:
employee
- attr1
- attr2
- user
- firstname
- lastname
My question: How to set the lastname of an employee as the value in the select field? I'm pretty sure it's possible, but I think I have some gaps in the syntax.
Why would you do that?
It's possible, with:
<%= f.collection_select :employee_id, #employees, :last_name, :text_method, :prompt => true %>
Where :text_method is method which called on #employees members will return text that you'd like to appear in dropdown.
You may be asking yourself why I have used <%= f.select %> this is FormOptionHelper on the Ruby on Rails Api this is very similar to collection_select however with that it returns and tags for the collection of values. Whereas select creates a series of contained option tags for provided object and method. So in saying this I believe you could have the following:
<%= f.select(:employee_id, Employee.all.collect { |emp| [emp.lastname, user.id] }
.sort{ |a, b| a[0] <=> b[0] }, {:prompt => "Select a Employee"}) %>
This selects all employees and sorts them in order of their last name.
I'm trying to create a select box that takes data from my db. I'm having trouble setting this up. I tried this code:
<%= f.fields_for :unit do |u| %>
<%= u.label :name %>
<%= u.select :name, :class => "ingredient_unit", :prompt => "Please Select" %>
<% end %>
but I'm missing the part of the choices, I don't know how to pull them out of the database. I tried using collection_select, which worked, but then the class option wasn't working... collection_select went like this:
<%= u.collection_select :unit, Unit.all, :id, :name, :class => "ingredient_unit", :prompt => "Please Select" %>
I also don't understand what the first symbol means (:unit), it seems to be setting the html id and name, so that can be anything I want it to be?
You should look at the documentation for collection_select and select. But to answer your question, for the select part, you forgot to pass the list of options to choose from. You also need to swap the order for prompt and class since prompt is an option for the helper and class is an html option
<%= u.select :unit_id, Unit.all.map { |u| [u.name, u.id] }, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
For the collection select
<%= u.collection_select :unit_id, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
The first parameter passed to both helper is the column name where you want the selected answer to be saved. The 2 codes above just shows 2 different ways to generate the same select tag.
The first symbol tells it which field to populate with the id returned from the user selection.
Also, you should wrap your class section in {}
:unit refers to the model attribute that you're using for the select element. Yes, it will setup the name/id of the element (and name is the most important for the params hash).
To set a class in the collection_select, specify it as a hash as that helper takes it as an html_option.
<%= u.collection_select :unit, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
The following produces a working select drop down that pulls from my user model:
<%= f.collection_select(:user_id, #users, :id, :firstname, options ={:prompt => "Select a User"} %>
I also have a column :lastname.
I am trying to populate the select with something like :firstname + " " + :lastname
This obviously fails if I just stick it in where :firstname is. How would you go about concatenating the two columns and populating the select box.
Thanks.
In your user model create a new method called name. Then use it in your helper.
class User
def name
"#{firstname} #{last_name}"
end
end
<%= f.collection_select(:user_id, #users, :id, :name, :prompt => "Select a User") %>
define a method full_name on the User model and then use :full_name in the collection select