在Rails中将DATETIME字段设置为零日期

Ben*_*ess 8 activerecord ruby-on-rails

我有一个Rails应用程序,它通过ActiveRecord管理MySQL数据库.我在该数据库中有一个DATETIME列,我想将其设置为零日期.(非空,零日期.向下滚动该页面以查看我的意思.)

看起来很简单,但我无法弄清楚如何在不使用原始SQL的情况下实现这一点.

以下是我已经尝试过的一些事情:

  • field = 0(因ActiveRecord错误而失败Column 'field' cannot be null)
  • field = "0000-00-00"(失败并出错undefined method 'year' for nil:NilClass)
  • field = DateTime.parse("0000-00-00")(失败,出现DateTime错误invalid date)

有没有办法通过ActiveRecord执行此操作,还是会被迫使用原始SQL?

编辑:我不允许改变我的SQL数据库的结构来解决这个问题.这是一件工作......

小智 10

看起来像"默认:0"做你想要的:

class CreateAnothers < ActiveRecord::Migration
  def change
    create_table :anothers do |t|
      t.date :start, null: false, default: 0
      t.timestamps null: false
    end
  end
end

 ? rake db:migrate
== 20150813201736 CreateAnothers: migrating ===================================
-- create_table(:anothers)
   -> 0.0943s
== 20150813201736 CreateAnothers: migrated (0.0944s) ==========================

[1] pry(main)> Another.create
   (0.2ms)  BEGIN
  SQL (0.5ms)  INSERT INTO `anothers` (`created_at`, `updated_at`) VALUES ('2015-08-13 20:19:02', '2015-08-13 20:19:02')
   (34.6ms)  COMMIT
=> #<Another:0x0000000ab8eb38 id: 1, start: nil, created_at: Thu, 13 Aug 2015 15:19:02 CDT -05:00, updated_at: Thu, 13 Aug 2015 15:19:02 CDT -05:00>

mysql> select * from anothers;
+----+------------+---------------------+---------------------+
| id | start      | created_at          | updated_at          |
+----+------------+---------------------+---------------------+
|  1 | 0000-00-00 | 2015-08-13 20:20:14 | 2015-08-13 20:20:14 |
+----+------------+---------------------+---------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

澄清要求后

那么,换句话说,你的目标是什么?您想通过rails运行更新来修改您的表吗?如果是这样,你可以做到

 ActiveRecord::Base.connection.execute("UPDATE table SET field='0000-00-00' WHERE id=#{self.id}")
Run Code Online (Sandbox Code Playgroud)

是允许的吗?(是)

更新

好吧,如果你想要它纯粹的Rails,那就这样吧:

[5] pry(main)> a.update_attribute(:start, nil)
   (1.5ms)  BEGIN
  SQL (3.6ms)  UPDATE `anothers` SET `start` = NULL, `updated_at` = '2015-08-14 16:31:22' WHERE `anothers`.`id` = 1
   (36.8ms)  COMMIT
=> true
[6] pry(main)> a.update_attribute(:start, "0000-00-00")
   (0.2ms)  BEGIN
   (0.1ms)  COMMIT
=> true

mysql> select * from anothers;
+----+-------+---------------------+---------------------+
| id | start | created_at          | updated_at          |
+----+-------+---------------------+---------------------+
|  1 | NULL  | 2015-08-14 16:30:39 | 2015-08-14 16:31:22 |
+----+-------+---------------------+---------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,update_attribute不起作用,但是

[8] pry(main)> a.update_column(:start, "0000-00-00")
  SQL (47.1ms)  UPDATE `anothers` SET `anothers`.`start` = '0000-00-00' WHERE `anothers`.`id` = 1
=> true

mysql> select * from anothers;
+----+------------+---------------------+---------------------+
| id | start      | created_at          | updated_at          |
+----+------------+---------------------+---------------------+
|  1 | 0000-00-00 | 2015-08-14 16:30:39 | 2015-08-14 16:31:22 |
+----+------------+---------------------+---------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

update_column呢!

请注意,在您执行此操作后a.update_column(:start, "0000-00-00"),变量上的日期字段(在我的情况下为"a.start")将设置为"0000-00-00".如果你想要它显示实际的nil值,你需要重新加载它,比如a.reload.