2009-06-10 5 views
4

私はtime_selectを使用してモデルに時間を入力し、いくつかの計算を実行しようとしています。Rails、非アクティブレコードモデルでtime_selectを使用

time_selectヘルパーは、戻り値であるパラメータを準備し、アクティブレコードオブジェクトへのマルチパラメータ割り当てで使用できるようにします。次

Parameters: {"commit"=>"Calculate", "authenticity_token"=>"eQ/wixLHfrboPd/Ol5IkhQ4lENpt9vc4j0PcIw0Iy/M=", "calculator"=>{"time(2i)"=>"6", "time(3i)"=>"10", "time(4i)"=>"17", "time(5i)"=>"15", "time(1i)"=>"2009"}} 
よう

何か

私の質問は、非アクティブレコードモデルでこの形式を使用するための最良の方法は何か、です。サイドノートにも。 (5i)、(4i)などの意味は何ですか?数は、あなたがそれがキャストされることを希望する種類を表した後、(他の異なる時間値を区別するための明白な理由、基本的には、なぜそれがこのように命名されたよりも)

答えて

4

はあなたが非アクティブレコードモデルにメソッドを作成することができます:-)

# This will return a Time object from provided hash 
def parse_calculator_time(hash) 
    Time.parse("#{hash['time1i']}-#{hash['time2i']}-#{hash['time3i']} #{hash['time4i']}:#{hash['time5i']}") 
end 

あなたはその後、呼び出すことができますが、次のように私に知らせてください方法をコントローラの動作から次のように変更します。

time_object = YourModel.parse_calculator_time(params[:calculator]) 

これは最適な解決策ではありませんが、使用するのは簡単です。

乾杯:

+0

非常に貴重な答えをありがとう。 – abhijit

2

手紙をいただきありがとうございます。この場合、integerfloatの場合はfstringの場合はsとすることもできます。

私はこれを自分で行いました。基本的にRailsコードをベースモジュール(または抽象オブジェクト)にコピー/ペーストすることが最も簡単な方法でした。

は、私はまた、/呼び出して、次の方法でそれらを使用している ActiveRecord::Base

  • assign_multiparameter_attributes(pairs)
  • extract_callstack_for_multiparameter_attributes(pairs)
  • type_cast_attribute_value(multiparameter_name, value)
  • find_parameter_position(multiparameter_name)

から逐語的に以下の機能をコピー:

def setup_parameters(params = {}) 
    new_params = {} 
    multi_parameter_attributes = [] 

    params.each do |k,v| 
    if k.to_s.include?("(") 
     multi_parameter_attributes << [ k.to_s, v ] 
    else 
     new_params[k.to_s] = v 
    end 
    end 

    new_params.merge(assign_multiparameter_attributes(multi_parameter_attributes)) 
end 

# Very simplified version of the ActiveRecord::Base method that handles only dates/times 
def execute_callstack_for_multiparameter_attributes(callstack) 
    attributes = {} 

    callstack.each do |name, values| 

    if values.empty? 
     send(name + '=', nil) 
    else 
     value = case values.size 
     when 2 then t = Time.new; Time.local(t.year, t.month, t.day, values[0], values[min], 0, 0) 
     when 5 then t = Time.time_with_datetime_fallback(:local, *values) 
     when 3 then Date.new(*values) 
     else nil 
     end 

     attributes[name.to_s] = value 
    end 

    end 

    attributes 
end 

あなたがよりよい解決策を見つけた場合は、

+0

このソリューションは、レール3または4用ですか? Rails 4では試してもうまくいかないようです。 –

+0

@MattHugginsこれは正直なところ、Rails 2のためであったかもしれないので、非常に***ですが、Rails 4では動作しません。 –

+0

これはRails 4.0.1の問題です。未解決の問題があります:https://github.com/rails/rails/pull/8189 –