How do I sort the drop-down list?

I’ve added a drop-down list of first and last names of borrowers to a
form. How do I sort them by LastName, FirstName in the drop-down?

I’m using code based on the cookbook example:

<% @borrowers.each do |borrower| %>

<%= borrower.FirstName << " " << borrower.LastName %>

<% end %>

Thanks from a raw newbie,
Shauna

Disclaimer: I’m fairly new to ruby and rails myself, so there is likely
a better way to do this, but I would sort the list in my controller and
then pass the sorted list to the view for the drop down list.

In the controller:

def yourAction
Borrower.find(:all, :order => “LastName DESC”).each do |borrower|
@borrowers = Array.new
@borrowers << borrower.LastName + borrower.FirstName
end
end

In the view:

<%= select(“borrowers”, “borrower_id”, options_for_select(@borrowers) %>

Hope that gets you going in the right direction. There are some
explanations of this in the API docs:

api.rubyonrails.org

Thanks for your reply. I’m trying to piece together everything I need
for my drop-down list from disparate sources and every little bit helps.

I also discovered (right after posting, of course) the
options_from_collection_for_select method of gathering the info. So far
I haven’t gotten that one to work at all yet, whereas my first attempt
(above) presents the desired selectable list of names but doesn’t insert
the borrower_id (my “Borrower does not exist” error message is being
triggered somehow).

The thing is, the drop-down list is not just for display. It’s on a
data-entry form for the loans table, which contains the foreign key
borrower_id (id in the borrower table). When the user selects a
FirstName + LastName from the drop-down list, I want my app to insert
the corresponding borrower id value into the loans table.

I know this is a simple, everyday thing to do but I can’t quite put my
examples together to get the complete functionality:

  1. retrieve the Borrower ids and names
  2. sort them by LastName, FirstName
  3. display the names in the drop-down as space
  4. default the selection to a chosen borrower handed in as an argument
  5. verify that the chosen borrower id exists and if so, insert its id
    into the borrower_id field in the loans record.
  6. The validation will eventually be done via Ajax methods so that the
    user doesn’t have to fill out the whole form before discovering
    an error in this field.

Can anyone suggest some code that incorporates all these aspects? I
already have the borrower/loan model working correctly (it prevents an
orphan loan from being added), and am working on the forms.

Thanks for helping out this ruby nuby!

Shauna

On 18 Aug 2006, at 11:46 pm, Shauna wrote:

I’ve added a drop-down list of first and last names of borrowers to a
form. How do I sort them by LastName, FirstName in the drop-down?

I’d do it something like this. In the controller, make a special
collection called @borrowers_for_select:

@borrowers = Borrower.find(:all, :order => “last_name, first_name”)
@borrowers_for_select = @borrowers.map{|b| [b.first_name + ’ ’ + b.last_name, b.id]}

Then in the view use:

<%= select(:loan, :borrower_id, @borrowers_for_select,
{:include_blank => true}) %>

There’s a lot going on here, so let’s work backwards.

First, the ‘select’ helper in the view. This constructs the entire
… lump for you. The parameters are:

  1. The name of the object that this input refers to (in this case,
    it’s @loan).
  2. The name of the attribute in that object that this input refers to
    (in this case, it’s @loan.borrower_id).
  3. A list of choices, formatted as an array of arrays:

[ [name1, value1],
[name2, value2],
[name3, value3], …]

where each ‘name’ is what appears in the drop-down list in the
browser, and each ‘value’ is what actually gets submitted when you
submit the form. So in your case, we want to put first_name+last_name
into the names, and the borrower IDs into the values.

Also note that the order of this array determines the order that the
choices will appear in the drop-down list.

  1. Misc. options, which in this case is the option :include_blank,
    which inserts a blank choice at the top of the list.

Now let’s look at the code in the controller. This line:

Borrower.find(:all, :order => “last_name, first_name”)

finds all of your borrowers, and then orders them by their last name
and then their first name. It’s generally neater to have your
database do the sorting for you wherever possible, rather than
sorting the array yourself.

Then, this line:

@borrowers.map{|b| [b.first_name + ’ ’ + b.last_name, b.id]}

uses the ‘map’ method of Array to transform the array of Borrower
objects into the format that we want for the ‘select’ helper in the
view. The ‘map’ method iterates through each member of @borrowers,
takes the result of the block (which in our case assembles a mini-
array for each borrower that looks like [name, id]), and slots it
into a new array. In other words, ‘map’ is a way of applying a given
bit of code to each member of an array.

Then, we have a @borrowers_for_select which is in the right format
for the ‘select’ helper in the view.

Does that all make sense? Let us know if you have any questions.

Chris

P.S. I’ve just realised that I used the style ‘first_name’ for your
column names instead of what you’ve got, which is ‘FirstName’. Change
as necessary (although if you want to be really Railsish you could
change your column names to the standard_rails_convention!).

Okay, I’ve found out how to address items 1, 2, and 3 on my list!

For other nubies, the answer was at the bottom of this page:
http://wiki.rubyonrails.org/rails/pages/HowtoUseFormOptionHelpers

For me what seems to work is:

<%= options_from_collection_for_select @borrowers.collect {|borrower| [borrower.id, borrower.FirstName + " " + borrower.LastName]}.sort{|x,y| x.last <=> y.last}, "first", "last", @loan.borrower_id %>

It looks like I’ll be able to address item 4 on my list by putting a
variable into the <option value = “” section.

Shauna