Rails associations and forms

Hmm, it seems that collection_select would work for the typical scenario:

<%= f.collection_select :stylist_id, Stylist.all, :id, :name %>

As much as RobinBrouwer's answer is correct, I just wanted to share a little nugget I came up with for one of our applications at work:

# config/initializers/to_options.rb
module ActiveRecord
  class Base
    def self.to_options(title=:name)
      self.all.map{|r| [r.send(title), r.id]}
    end
  end
end

Now, you can use to_options on any model, with the flexibility of picking any field for the option text (which defaults to name).

Model.to_options # => Creates select options with [m.name, m.id]
AnotherModel.to_options(:title) # => Creates select options with [m.title, m.id]

Shouldn't be hard to modify with ordering if necessary, either.


This answer improves performance on @vonconrad 's answer taking advantage of Rail's optimized .pluck vs .map by orders of magnitude especially if used on models with high number of records, though you likely would not used the entire options model method in a view for example.

module ActiveRecord
  class Base
    def self.to_options(title=:name)
      self.pluck(title.to_sym, :id)
    end
  end
end

Here are the benchmark results on a data model with nearly 300k records with the first version using .all.map and with the improved .pluck way.

 15.560000   2.950000  18.510000 ( 19.059607)
  0.390000   0.020000   0.410000 (  0.539866)

=> [
    [0] #<Benchmark::Tms:0x00007fb6091fa628 @label="all", @real=15.474819000111893, @cstime=0.0, @cutime=0.0, @stime=0.5800000000000001, @utime=14.480000000000004, @total=15.060000000000004>,
    [1] #<Benchmark::Tms:0x00007fb5f6a52978 @label="pluck", @real=0.8451100001111627, @cstime=0.0, @cutime=0.0, @stime=0.10000000000000009, @utime=0.5999999999999943, @total=0.6999999999999944>
]