Reputation: 99
I have Rails app with a use case to display prices in a collection_select dropdown box. For instance, names of products and their prices, or clients and amounts owing.
I well know it's bad MVC practice to simply include the relevant helpers to get access to functions like number_to_currency, but the best I can do with a custom method on the Product or Payment model is get a value that looks like $20.2. So, it's readable but sub-optimal in that most users of the system will be expecting twenty dollars and twenty cents to be represented as $20.20.
Does anyone have any suggestions for easily customising the text_method of a collection_select?
Upvotes: 2
Views: 1201
Reputation: 99
I ended up building on GoGoCarl's suggestion, but moving the array generation to a helper:
module PaymentsHelper
def invoices_for_payment_select(invoice)
@invoices.collect { |i| ["#{i.client.name} - #{number_to_currency(i.outstanding)}", i.id] }
end
end
This way I can reuse the dropdown box should I need to and keep the view neat.
Upvotes: 0
Reputation: 15934
The text_method
as well as the value_method
in collection_select
accepts a symbol but also a lambda/proc block which will get the current collection element as a parameter. See the docs here. The lambda is executed in the context of the view so all view helpers should be available inside it.
So to get the model price formatted by a currency formatter you should be able to call collection_select
like the following:
<%= collection_select :user, :payment_id, @user.payments,
:id, ->(pmt) { number_to_currency(pmt.amount) } %>
You have not shown your model associations, so this is just an example of a user having many payments for which you want to format the price in the select box text.
Upvotes: 5
Reputation: 2519
Abandon ship with the collection_select
method, and just use select
in your view:
<% options = @payments.each { |p| number_to_currency(p.price), p.id } %>
<%= f.select :payment, options %>
Since you're in the view, everything you'd expect is there, both model and helper methods.
I'm making assumptions on your HTML since you didn't give a specific example, but I think the code block above is everything you need to get going. For more details: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
If you are married to collection_select
, you could always roll your own number formatter for currency; shouldn't be difficult with pure Ruby. But, the method above will be more powerful in the long run and afford your more options with helpers down the line, and let you use functions consistently across views.
Upvotes: 2