2012-06-21 9 views
10

私はレールが初めてですので、あまりにも簡単な場合はごめんなさい。1つの属性に複数の入力フィールドを使用する

私のモデルにdatetime属性があり、3つのフォーム要素で値を入れようとしています。 最初のものは日付用で入力フォームです(私はbootstrap-datepicker-railsを使用しています。 2番目の選択肢では、時間帯の選択ボックスがあり、3番目の選択肢は分です。

私はDateHelpers datetime_selectを使用することができましたが、もうbootstrap-datepickerを使用することはできません。 それでは、複数のフォーム入力要素を使用して属性(datetime)を満たす適切な方法は何ですか。私はassign_multiparameter_attributesのようなものがあることを見たが、ドキュメントはかなり。モデルがまだ有効である:-(

おかげ

答えて

10

私にとって、これは解決するためにコントローラの問題のように思える助けにはならないと正常に動作します私の解決策はコントローラがparamsハッシュを変更して、モデルがビューの変更を認識しないようにすることです。これはプライベートAPIと考えられるbehavior in ActiveRecordに依存しますが、だから...公正​​な警告:-)

あなたはこのモデルを持っていると言っています:

# app/models/example.rb 
class Example < ActiveRecord::Base 
    attr_accessible :started_at # this is a DateTime 
end 

(ブートストラップ日付ピッカーによって強化されます)日付部分の通常text_field_tagを使用するようにビューを調整し、Railsののtime_select時間部分のため:私たちは以来tryを使用している

# app/views/examples/_form.html.erb 
<%= form_for(@example) do |f| %> 
    <p> 
    <%= f.label :started_at %> 
    <%= text_field_tag :started_at, @example.started_at.try(:to_date) %> 
    <%= f.time_select :started_at, :ignore_date => true %> 
    </p> 

    <p><%= f.submit %></p> 
<% end %> 

お知らせこのフォームは新しいの永続レコード用にレンダリングされます。これにより、started_at属性がnilの場合の問題が回避されます。

class ExamplesController < ApplicationController 
    before_filter :fix_params, :only => [:create, :update] 

    # ... 

private 

    def fix_params 
    date = Date.parse(params.delete(:started_at)) 

    params[:example].merge!({ 
     'started_at(1i)' => date.year.to_s, 
     'started_at(2i)' => date.month.to_s, 
     'started_at(3i)' => date.day.to_s 
    }) 
    end 
end 

は基本的に、我々は日付としてparams[:started_at]を解析し、params[:example]の正しいキーに割り当てている:

そして、それがモデルに送られる前にparamsハッシュを修正するために、コントローラにbefore_filterを作成。その後、パラメータが最終的にモデルに渡されると、ActiveRecordはモデルのstarted_at属性を正しく割り当てます。

いくつかのエラーチェックと検証が必要ですが、これはうまくいくはずです。

+1

"fix_params"の最初の行はparams [:example]を持つ必要があります。それ以外の場合はnilになります。 –

+0

これは事実ではありません。 'f.text_field'の代わりに' text_field_tag'を使っているので、テキストフィールドの名前は 'example [started_at]'ではなく 'started_at'です。だから、 'params'ハッシュのトップレベルで生きています。 – Brandan

+1

ああ、私はそれをスキップしました。私はf.text_fieldでこのように実装しましたが、うまくいきます。 –

関連する問題