복붙노트

[RUBY-ON-RAILS] 3 sqlite3를 부울 거짓 레일

RUBY-ON-RAILS

3 sqlite3를 부울 거짓 레일

내가 sqlite3를 테이블에 거짓 부울 값을 삽입하기 위해 노력하고있어하지만 항상 true 값을 삽입합니다.

여기 내 마이그레이션입니다 :

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :name, :string
      t.column :active, :boolean, :default => false, :null => false
    end
  end

  def self.down
    drop_table :resources
  end
end

때 나는 다음과 같은 SQL을 생성 레일을 사용하여 삽입하려고 :

INSERT INTO "users" ("name", "active") VALUES ('test', 'f')

SQLite는 치료 'F'내 데이터베이스에 진정한 삽입 그래서 사실로. 나는 그것을 생성 할 쿼리는 다음과 같습니다

INSERT INTO "users" ("name", "active") VALUES ('test', false)

내가 도대체 ​​뭘 잘못하고있는 겁니까?

레일 : 3.0.7

sqlite3를 보석 : 1.3.3

해결법

  1. ==============================

    1.SQLite는 거짓 true를 1과 0을 사용합니다 :

    SQLite는 거짓 true를 1과 0을 사용합니다 :

    하지만 SQLite는 또한 느슨한 타입 시스템을 가지고 있으며, 자동으로 물건을 캐스팅 귀하의 'F'는 아마 0이 아닌 단순히 때문에 "진실"의 truthiness있는 것으로 해석되고있다.

    파고의 비트는 레일 3.0.7 SQLiteAdapter에서 버그를 발견했음을 나타냅니다. active_record / connection_adapters / 초록 /의 quoting.rb에서, 우리는 다음을 찾을 수 :

    def quoted_true
      "'t'"
    end
    
    def quoted_false
      "'f'"
    end
    

    그래서 기본적으로 액티브 데이터베이스가 부울 열에 대해 't'와 'F'를 이해하고 있다고 가정합니다. MySQL의 어댑터는 부울 열은 TINYINT의 구현 작업에 이러한 우선합니다 :

    QUOTED_TRUE, QUOTED_FALSE = '1'.freeze, '0'.freeze
    
    #...
    
    def quoted_true
      QUOTED_TRUE
    end
    
    def quoted_false
      QUOTED_FALSE
    end
    

    하지만 SQLite는 어댑터는 quoted_true의 자신의 구현을 제공하거나 SQLite는의 논리 값과 일을하지 않는 기본값을 얻을 수 있도록 quoted_false하지 않습니다.

    PostgreSQL의에서 't'와 'F'부울 작업은 어쩌면 모두가 레일 3의 PostgreSQL을 사용 또는 그들은 단지 자신의 쿼리가 제대로 작동하지 않는 것을 알아 차리지 아닙니다.

    나는이 놀랄 조금있어 희망 누군가가 내가 사라 잘못했습니다 곳, 당신은 레일 3 SQLite는의 부울 열을 사용하는 최초의 사람이 될 수 없습니다 지적 할 수있다.

    :: 액티브 :: ConnectionAdapters에 SQLiteAdapter (또는 active_record / connection_adapters / sqlite_adapter.rb에 일시적으로 손으로 편집을) 말을하고 분별 얻을 수 있는지, '0', '1'; 데프 quoted_false 끝을 데프 quoted_true 패치 원숭이 시도 SQL.

  2. ==============================

    2.내가 어떻게 여기 원숭이 패치입니다뿐만 아니라이 가로 질러 :

    내가 어떻게 여기 원숭이 패치입니다뿐만 아니라이 가로 질러 :

    require 'active_record/connection_adapters/sqlite_adapter'
    module ActiveRecord
      module ConnectionAdapters
        class SQLite3Adapter < SQLiteAdapter
          def quoted_true; '1' end
          def quoted_false; '0' end
        end
      end
    end
    

    나는 아직도이 버그에 걸쳐 실행하고있어 어떻게하지 않는다?

  3. ==============================

    3.당신은 SQLite는 부울 열이 실제로 레일 4 (도 https://gist.github.com/ajoman/9391708에 게시) 작업과의 호환성을 추가하기위한 유용한 다음과 같은 코드를 찾을 수 있습니다 :

    당신은 SQLite는 부울 열이 실제로 레일 4 (도 https://gist.github.com/ajoman/9391708에 게시) 작업과의 호환성을 추가하기위한 유용한 다음과 같은 코드를 찾을 수 있습니다 :

    # config/initializers/sqlite3_adapter_patch.rb
    
    module ActiveRecord
      module ConnectionAdapters
        class SQLite3Adapter < AbstractAdapter
          QUOTED_TRUE, QUOTED_FALSE = "'t'", "'f'"
    
          def quoted_true
            QUOTED_TRUE
          end
    
          def quoted_false
            QUOTED_FALSE
          end
        end
      end
    end
    
  4. ==============================

    4.이은 (는) 안정적인 최신 릴리스 (5.1.4)의 일부가 아닙니다 그러나 7월 12일 2017 년에 마스터에서 수정되었습니다. 이 고정 된 것 가장 최근 버전은 v5.2.0.rc1입니다.

    이은 (는) 안정적인 최신 릴리스 (5.1.4)의 일부가 아닙니다 그러나 7월 12일 2017 년에 마스터에서 수정되었습니다. 이 고정 된 것 가장 최근 버전은 v5.2.0.rc1입니다.

    동작은 (기본값은 사실이다) Rails.application.config.active_record.sqlite3.represent_boolean_as_integer를 통해 설정할 수 있습니다.

  5. ==============================

    5.이 버전은 레일 4.1에서 작동합니다.

    이 버전은 레일 4.1에서 작동합니다.

    require 'active_record/connection_adapters/sqlite_adapter'
    
    module ActiveRecord::ConnectionAdapters::SQLite3Adapter
      QUOTED_TRUE, QUOTED_FALSE = 't'.freeze, 'f'.freeze
    
      def quoted_true; QUOTED_TRUE end
      def quoted_false; QUOTED_FALSE end
    end
    

    루비는 그 문자열을 다시 쓰레기는 모든 통화를 수집하지 않도록 상수 및 .freeze는 성능이다.

  6. from https://stackoverflow.com/questions/6013121/rails-3-sqlite3-boolean-false by cc-by-sa and MIT license