迁移到postgresql - Create Action不再起作用

时间:2011-12-13 21:49:52

标签: ruby-on-rails postgresql

我最近迁移到postgresql,因为我必须稍后将我的应用程序部署到heroku。

但我遇到了一些问题。

模型转换的“我的创建”操作不再起作用:

错误消息是:

2 error(s) on assignment of multiparameter attributes 

模特:

class Shift < ActiveRecord::Base
    attr_accessible :starts_at, :ends_at, :happens_on, :employee_id

    belongs_to :employee
    has_one :company, :through => :employee

    validates :employee_id, :presence => true


    validates :happens_on, :presence => true
    validates :starts_at, :presence => true
    validates :ends_at, :presence => true
 end

控制器操作“创建”:

def create
  @title = "New Shift"    

  @shift = Shift.new(params[:shift])        

  if @shift.save
    redirect_to shifts_path, :flash => { :success => 'Shift created!' }
  else
    render action: "new"
  end
end

获取参数:

{"utf8"=>"✓",
 "authenticity_token"=>"dH017fvWEGUWj3VPi7TssjL3BpjxzcC4Idjjc=",
 "shift"=>{"employee_id"=>"3",
 "happens_on"=>"12/15/2011",
 "starts_at(5i)"=>"06:00:00",
 "ends_at(5i)"=>"09:30:00"},
  "commit"=>"Create Shift"}

我的表格:

<%= simple_form_for @shift, :wrapper => :inline do |f| %>

<% if f.error_notification %>
<div class="alert-message error fade in" data-alert="alert">
 <a class="close" href="#">×</a>
 <p><%= f.error_notification %></p>
</div>
<% end %>

<%= f.association :employee, :input_html => { :class => "span4" }%>
<%= f.input :happens_on, :input_html => { :class => "span4" }, :as => :date_picker %>
<div class="clearfix">
<label for="shift_starts_at_5i">Start Time</label>
<div class="input"><%= time_select "shift", "starts_at", { :default => Time.now.change(:hour => 21), :simple_time_select => true, :minute_interval => 30, :time_separator => "", :start_hour => 6, :end_hour => 20 } %>
</div></div>
<div class="clearfix">
<label for="shift_ends_at_5i">End Time</label>
<div class="input"><%= time_select "shift", "ends_at", { :default => Time.now.change(:hour => 21), :simple_time_select => true, :minute_interval => 30, :time_separator => "", :start_hour => 6, :end_hour => 20 } %>
</div></div>

  <div class="actions">
      <%= f.button :submit, :class => 'primary' %>
      <%= button_tag 'Cancel', :type => :reset, :class => "btn" %>
  </div>
<% end %>

编辑: time_select代码:

  module ActionView::Helpers
    class DateTimeSelector
       def select_minute_with_simple_time_select
          return select_minute_without_simple_time_select unless @options[:simple_time_select].eql? true

          # Although this is a datetime select, we only care about the time.  Assume that the date will
          # be set by some other control, and the date represented here will be overriden

          val_minutes = @datetime.kind_of?(Time) ? @datetime.min + @datetime.hour*60 : @datetime

          @options[:time_separator] = ""

          # Default is 15 minute intervals
          minute_interval = 15
          if @options[:minute_interval] 
            minute_interval = @options[:minute_interval] 
          end

          start_minute = 0
          # @options[:start_hour] should be specified in military
          # i.e. 0-23
          if @options[:start_hour]
            start_minute = @options[:start_hour] * 60
          end

          end_minute = 1439
          # @options[:end_hour] should be specified in military
          # i.e. 0-23
          if @options[:end_hour]
            end_minute = ( @options[:end_hour] + 1 ) * 60 - 1  
          end

          if @options[:use_hidden] || @options[:discard_minute]
            build_hidden(:minute, val)
          else
            minute_options = []
            start_minute.upto(end_minute) do |minute|
              if minute%minute_interval == 0
                ampm = minute < 720 ? ' AM' : ' PM'
                hour = minute/60
                minute_padded = zero_pad_num(minute%60)
                hour_padded = zero_pad_num(hour)
                ampm_hour = ampm_hour(hour)

                val = "#{hour_padded}:#{minute_padded}:00"
                minute_options << ((val_minutes == minute) ? 
                  %(<option value="#{val}" selected="selected">#{ampm_hour}:#{minute_padded}#{ampm}</option>\n) :
                  %(<option value="#{val}">#{ampm_hour}:#{minute_padded}#{ampm}</option>\n)
                )
              end
            end
            build_select(:minute, minute_options.join(' '))
          end
        end
        alias_method_chain :select_minute, :simple_time_select


        def select_hour_with_simple_time_select
          return select_hour_without_simple_time_select unless @options[:simple_time_select].eql? true
          # Don't build the hour select
          #build_hidden(:hour, val)
        end
        alias_method_chain :select_hour, :simple_time_select

        def select_second_with_simple_time_select
          return select_second_without_simple_time_select unless @options[:simple_time_select].eql? true
          # Don't build the seconds select
          #build_hidden(:second, val)
        end
        alias_method_chain :select_second, :simple_time_select

        def select_year_with_simple_time_select
          return select_year_without_simple_time_select unless @options[:simple_time_select].eql? true
          # Don't build the year select
          #build_hidden(:year, val)
        end
        alias_method_chain :select_year, :simple_time_select

        def select_month_with_simple_time_select
          return select_month_without_simple_time_select unless @options[:simple_time_select].eql? true
          # Don't build the month select
          #build_hidden(:month, val)
        end
        alias_method_chain :select_month, :simple_time_select

        def select_day_with_simple_time_select
          return select_day_without_simple_time_select unless @options[:simple_time_select].eql? true
          # Don't build the day select
          #build_hidden(:day, val)
        end
        alias_method_chain :select_day, :simple_time_select

    end
  end

  def ampm_hour(hour)
    return hour == 12 ? 12 : (hour == 0 ? 12 : (hour / 12 == 1 ? hour % 12 : hour))
  end

  def zero_pad_num(num)
    return num < 10 ? '0' + num.to_s : num.to_s
  end

1 个答案:

答案 0 :(得分:1)

我猜您收到有关starts_at(5i)ends_at(5i)的投诉,并且您将starts_atends_at定义为日期时间或时间戳。我猜你也是来自SQLite。 SQLite有一个非常松散的类型系统,PostgreSQL是非常严格的;如果您尝试将'06:00:00'放入PostgreSQL时间戳列,PostgreSQL会抱怨,因为时间戳需要日期和时间组件。

如果上述情况正确,请尝试将您的starts_atends_at列更改为简单time列,迁移中的此类操作可能会起到作用:

def up
    change_column :shifts, :starts_at, :time, ...
    change_column :shifts, :ends_at, :time, ...
end