2014-01-06 11 views
11

Vor einiger Zeit aufgerüstet wir unsere Anwendung Rails 4 und wechselte zu JRuby.Rails Migration erzeugt Standardzeitstempel (created_at, updated_at) als NULLABLE

Vor dieser Änderung erstellten Migrationen die Standardzeitstempel NOT NULL. Nach dieser Änderung fehlt die NOT NULL fehlt.

Wir schaffen diese Zeitstempel (created_at, updated_at) wie folgt:

class Model < ActiveRecord::Migration 
    def change 
    create_table :model do |t| 
     t.belongs_to :user, :null => false 

     t.text :content 

     t.timestamps 
    end 
    end 
end 

Die wichtigen Teile unserer Anwendung sind:

  • Rubin '1.9.3': Motor => ‚jruby ‘: engine_version => '1.7.9'
  • Juwel 'Schienen', '4.0.2'
  • gem 'active-jdbcpostgresql-Adapter', '1.3.4'
  • postgresql: stabile 9.3.1

Haben Sie eine Ahnung, was das Problem verursachen könnten und wie können wir die Standard-Generation zurück zu NOT NULL ändern?

Antwort

7

Ich weiß nicht, ob es irgendwo dokumentiert ist aber the source zeigt an, dass Sie die üblichen Spaltenoptionen zu t.timestamps passieren kann:

# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and 
# <tt>:updated_at</tt> to the table. 
def timestamps(*args) 
    options = args.extract_options! 
    column(:created_at, :datetime, options) 
    column(:updated_at, :datetime, options) 
end 

so kann man sagen:

create_table :model do |t| 
    #... 
    t.timestamps :null => false 
end 

und Ihre Spalten sollte NICHT NULL sein.

Wenn man sich die 3.2 version anschauen, werden Sie sehen, was passiert ist:

def timestamps(*args) 
    options = { :null => false }.merge(args.extract_options!) 
    #... 
end 

so 3.2 erzeugt die Zeitstempel-Spalten als NOT NULL standardmäßig aber 4.0 nicht.

+1

Groß, danke. Das ist es. Ich wundere mich, dass niemand sonst ein Problem mit dieser Änderung hat. Es hat wirklich einen großen Einfluss darauf, was Sie von Ihren Migrationen erwarten können. – maerzbow

+0

Der Rails-Standard ist ': null => true' (was mit dem törichten Standard von SQL übereinstimmt) und ich habe den Eindruck, dass': null => false' auf 't.timestamps' nicht konsistent behandelt wurde. Vermutlich haben sie sich dafür entschieden, es konsistent zu machen, indem es mit dem Rest von Rails übereinstimmt. Eine Menge von ARs Interaktion mit relationalen Datenbanken verwirrt mich, um ehrlich zu sein. –

+3

FWIW, es sieht so aus, als hätten Zeitstempel 'null: false' standardmäßig nur in der 3.2 Zeile. Es wurde in [rails/rails # 3334] (https://github.com/rails/rails/pull/3334) und dann [reverted] hinzugefügt (https://github.com/rails/rails/commit/fcef728). vor 4.0. –

0

Dieses Problem mir wütend gemacht, weil ich eine alte app hatte, die auf Rails 3.2 für ein paar Jahre gewesen war, mit einer großen Anzahl von Nutzungen dieses Verfahrens, daher ist dieser initializer:

# Force t.timestamps to always be null: false 
module ActiveRecord 
    module ConnectionAdapters 
    class TableDefinition 

     def timestamps_with_non_nullable(*args) 
     options = args.extract_options! 
     options.merge!(null: false) 
     timestamps_without_non_nullable(*args, options) 
     end 
     alias_method_chain :timestamps, :non_nullable 

    end 
    end 
end