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.