多选菜单和虚拟属性

时间:2010-03-11 09:16:34

标签: ruby-on-rails ruby

我的句号表有start_at:datetime end_at:datetime。 因为每个时段在同一天开始和结束,所以我想将三个字段分开而不是两个。

字段1:日期 字段2:开始的时间“00:00” 字段3:结束时间“00:00”

我开始做了这个。但不幸的是,我遇到了一个问题。

所以请看一下周期模型,表格和错误,并纠正我,纠正代码。

提前致谢!

期间模型

class Period < ActiveRecord::Base
  belongs_to :show

  def show_date; start_at.nil? ? Time.now.to_date : start_at.to_date; end
  def start_at_time; start_at.nil? ? Time.now.to_time : start_at.to_time; end
  def end_at_time; end_at.nil? ? Time.now.to_time : end_at.to_time; end

  def start_at_time=(start_str)
   self.start_at = DateTime.parse("#{show_date.strftime("%Y-%m-%d")}T#{start_str.strftime("%H:%M:%S")}")
  end

  def end_at_time=(end_str)
   self.end_at = DateTime.parse("#{show_date.strftime("%Y-%m-%d")}T#{end_str.strftime("%H:%M:%S")}")
  end
end

期间架构

#just the schema for periods table
  create_table "periods", :force => true do |t|
    t.integer "show_id"
    t.datetime "start_at"
    t.datetime "end_at"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

_form.html.erb

  <div class="group">
    <%= f.label :show_id, "Show", :class => :label %>
    <%= f.collection_select :show_id, @shows.collect, :id, :name %>
    <span class="description">Select the show</span>
  </div>

  <div class="group">
    <%= f.label :show_date, "Date at", :class => :label %>
    <%= f.date_select :show_date, :class => 'datetime_select' %>
    <span class="description">Date of the show</span>
  </div>

  <div class="group">
    <%= f.label :start_at_time, "Start at", :class => :label %>
    <%= f.time_select :start_at_time, {:minute_step => 15, :ignore_date => true}, :class => 'datetime_select' %>
    <span class="description">Time :: When does it start?</span>
  </div>

  <div class="group">
    <%= f.label :end_at_time, "End at", :class => :label %>
    <%= f.time_select :end_at_time, {:minute_step => 15, :ignore_date => true}, :class => 'datetime_select' %>
    <span class="description">Time :: When does it end?</span>
  </div>

  <div>
    <button class="button" type="submit"><%= image_tag("tick.png", :alt => "Save") %> Save</button>
  </div>

错误

==Framework Trace 

3 error(s) on assignment of multiparameter attributes



==Framework Trace 

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:3073:in `execute_callstack_for_multiparameter_attributes'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:3028:in `assign_multiparameter_attributes'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2750:in `attributes='
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2628:in `update_attributes'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:1331:in `send'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:1331:in `perform_action_without_filters'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/filters.rb:617:in `call_filters'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/home/amrnt/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/amrnt/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/rescue.rb:160:in `perform_action_without_flash'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/flash.rb:146:in `perform_action'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:532:in `send'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:532:in `process_without_filters'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/filters.rb:606:in `sass_old_process'
/usr/lib/ruby/gems/1.8/gems/haml-2.3.0/lib/sass/plugin/rails.rb:19:in `process_without_compass'
/home/amrnt/cc/vendor/gems/compass-0.8.17/lib/compass/app_integration/rails/action_controller.rb:7:in `process'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:391:in `process'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/base.rb:386:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/routing/route_set.rb:437:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:87:in `dispatch'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:121:in `_call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:130:in `build_middleware_stack'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:29:in `call'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:29:in `call'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:9:in `cache'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/query_cache.rb:28:in `call'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/string_coercion.rb:25:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/head.rb:9:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/methodoverride.rb:24:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/params_parser.rb:15:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/session/cookie_store.rb:93:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/failsafe.rb:26:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:114:in `call'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/reloader.rb:34:in `run'
/home/amrnt/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/dispatcher.rb:108:in `call'
/usr/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/rails/rack/static.rb:31:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:46:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:40:in `each'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:40:in `call'
/usr/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/rails/rack/log_tailer.rb:17:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/content_length.rb:13:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/chunked.rb:15:in `call'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/handler/mongrel.rb:64:in `process'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run'
/home/amrnt/.gem/ruby/1.8/gems/rack-1.0.1/lib/rack/handler/mongrel.rb:34:in `run'
/usr/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:111
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
script/server:3



==Request Parameters:

{"period"=>{"start_at_time(4i)"=>"20",
 "start_at_time(5i)"=>"00",
 "end_at_time(4i)"=>"23",
 "end_at_time(5i)"=>"30",
 "show_date(1i)"=>"2010",
 "show_date(2i)"=>"3",
 "show_date(3i)"=>"31",
 "show_id"=>"1"},
 "_method"=>"put",
 "authenticity_token"=>"pm/cXQQnOCsidcAj/OEJuMtHgfppZvoqq09epdETAxo=",
 "id"=>"46"}

1 个答案:

答案 0 :(得分:3)

ActionView中包含的date and time form helpers生成使用称为“多参数分配”的特殊表单元素。这意味着当您提交date_selectdatetime_selecttime_select表单字段时,它们会生成几个由ActiveRecord编译为一个日期,日期时间或时间对象的独立参数。在您的情况下,这些参数如下所示:

 "start_at_time(4i)"=>"20",
 "start_at_time(5i)"=>"00"

 "end_at_time(4i)"=>"23",
 "end_at_time(5i)"=>"30"

 "show_date(1i)"=>"2010",
 "show_date(2i)"=>"3",
 "show_date(3i)"=>"31"

我应该注意,这些与您在Period模型的start_at_time=end_at_time=方法中所期望的字符串非常不同,并且您的模型没有show_date=方法所有。

带有括号的参数格式是Rails用于多参数分配的参数格式。但是,ActiveRecord依赖于相应的数据库列,以便了解提交的多个参数是否代表日期,时间或日期时间对象。这意味着帮助程序不会对虚拟属性起作用,至少是开箱即用的。没有办法告诉他们期望什么样的对象。

至少有一张活动门票:

https://rails.lighthouseapp.com/projects/8994/tickets/2675-support-for-multiparameter-attribute-assignment-on-virtual-attribute-writers

您可以在此链接中找到有关多参数分配和使用Rails的日期表单助手的精彩概述:

http://www.alexrothenberg.com/2009/05/how-to-use-dates-in-rails-when-your.html

关于此设计的一般改进:如果每个句点在同一天开始和结束,为什么不使用date属性来存储句点日期和两个time属性来存储开始和结束倍。您可以轻松创建返回从这些属性编译的start_atend_at日期时间对象的方法。

您可以使用表单助手或多或少地设置表单。您还可以轻松地在end_time属性上设置验证,确保它始终在当天晚些时候,而不是start_time