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):


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.

I would appreciate some guidance.

Kind regards,

Andre Foeken

DrRaven wrote:

@unit   = Unit.find(:first)

class StateController < ApplicationController

<% @state = current_state %>
<% 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.


We develop, watch us RoR, in numbers too big to ignore.