在Rails

时间:2015-08-11 16:53:26

标签: ruby-on-rails activerecord

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

看起来很简单,但我无法弄清楚如何在不使用原始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")(失败,日期时间错误为invalid date

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

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

2 个答案:

答案 0 :(得分: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)

澄清要求后

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

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

允许吗? (YES)

<强>更新

好的,如果你想要它纯粹的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)

正如您所看到的,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)

update_column 可以!

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

答案 1 :(得分:-1)

我想这不适用于正确的格里高利历,因为没有第0年:https://en.wikipedia.org/wiki/0_(year)

也许请尝试01-01-0001年。