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

看起来很简单,但是我不知道如何在不使用原始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数据库的结构来解决此问题。这是一件工作的事...

    最佳答案

    看起来像“默认值: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运行update来修改您的表吗?如果是这样,您可以
     ActiveRecord::Base.connection.execute("UPDATE table SET field='0000-00-00' WHERE id=#{self.id}")
    

    可以吗(是的)

    更新

    好的,如果您想要纯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")之后,变量上的日期字段(在我的情况下为“a.start”)将设置为“0000-00-00”。而且,如果您希望它显示实际的nil值,则需要像a.reload一样重新加载它。

    关于ruby-on-rails - 在Rails中将DATETIME字段设置为零日期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31947625/

    10-12 14:22
    查看更多