Collection_select troubles

Hi all,

I'm relatively new to Rails and I am just figuring out how everything
works. I've been mostly impressed with the way things work but I have
one issue. Most of the rails code seems so elegant so I have to assume
it's my fault for not finding the proper way to do this. I'll explain:

I have a model (session based, so no ActiveRecord):

DrRaven wrote:

I have a model (session based, so no ActiveRecord):

----

class State
  attr_reader :period, :unit
  attr_writer :period, :unit

  def initialize
    @period = Period.find(:first)
    @unit = Unit.find(:first)
  end

end

----

And a controller:

----

class StateController < ApplicationController

  def update
    @state = session[:state]

    @state.period = Period.find(params[:state][:period])
    @state.unit = Unit.find(params[:state][:unit])

  end

end

----

So far so good. What I want is a simple Ajax form that can update my
'State' model using several select boxes. This seems to work quite
alright except for one thing: the form doesn't show my current
selection. So when I save my 'Unit' and 'Period' into the 'State'
model, they both get saved alright (I've checked this) but the
selection box shows default values.

I've solved the problem by using the (ugly) select_tags:

----

<% @state = current_state %>

<% remote_form_for :state, @state, :url => { :controller => 'state',
:action => 'update' } do |f| %>

<%= select_tag 'state[period]',
options_from_collection_for_select(Period.find(:all), :id, :name,
@state.period.id), { 'onchange' => 'this.form.onsubmit();' } %>

<%= select_tag 'state[unit]',
options_from_collection_for_select(Unit.find(:all), :id, :name,
@state.unit.id), { 'onchange' => 'this.form.onsubmit();' } %>

<% end %>

----

But what I want (and would make the purist in me happy) is:

<% @state = current_state %>

<% remote_form_for :state, @state, :url => { :controller => 'state',
:action => 'update' } do |f| %>

<% f.collection_select :period, Period.find(:all), :id, :name, {}, {
'onchange' => 'this.form.onsubmit();' } %>

<% f.collection_select :unit, Unit.find(:all), :id, :name, {}, {
'onchange' => 'this.form.onsubmit();' } %>

<% end %>

----

Can anyone tell me why the selection is not shown. I have done some
testing myself and I believe the problem lies with the fact that
somehow it fails to correctly compare the @state.period (which it gets
from the form's object + collection_select's method_name fields) with
the Period.find(:all) version of the object. I also tried to rewrite
the entire thing using just the id's (integers) but that doesn't seem
to work either.

For

<% f.collection_select :period, Period.find(:all), :id, :name, {} %>

The selected value is @state.period, which is a Period object that
can never equal an the value of an option, which are id Integers.

If you really wanted to make this work you could:

1. In your State model add method

       def period_id
         period.id
       end

    and use :period_id as the method in your collection select

2. In your Period model define

      def identity
        self
      end

      def to_s
        id
      end

    And use the identity method as your collection select value method.