簡體   English   中英

如何防止Ruby on Rails Active記錄從數據庫中獲取默認模型值?

[英]How to prevent Ruby on Rails Active record from getting default model values from the database?

我正在開發一個RoR應用程序,Firebird和它的SQL引擎,但我不明白為什么ActiveRecord(AR)一直在查詢數據庫的默認值!

這是表DDL:

CREATE TABLE GLOBAL_SETTINGS
(
  SKEY varchar(64) NOT NULL,
  SVALUE varchar(256) NOT NULL,
  OBS blob sub_type 1,
  IS_SYSTEM "BOOLEAN" DEFAULT 1 NOT NULL,
  CREATED_AT timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
  UPDATED_AT timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
  CONSTRAINT PK_GLOBAL_SETTINGS_SKEY PRIMARY KEY (SKEY)
);

以下是創建此表的遷移:( create_global_settings.rb

class CreateGlobalSettings < ActiveRecord::Migration
  def up
    create_table :global_settings, :id => false do |t|
      t.string :skey, :null => false, :limit => 64
      t.string :svalue, :null  => false, :limit => 256
      t.text :obs
      t.boolean :is_system, :null  => false, :default => true
      t.timestamps :null  => false
    end

    # defaults on timestamp columns
    execute("alter table GLOBAL_SETTINGS alter column CREATED_AT set default     CURRENT_TIMESTAMP;")
    execute("alter table GLOBAL_SETTINGS alter column UPDATED_AT set default     CURRENT_TIMESTAMP;")    

    # our custom PK naming
    execute("alter table GLOBAL_SETTINGS add constraint PK_GLOBAL_SETTINGS_SKEY primary     key (SKEY)")    
  end

  def down
    drop_table :global_settings
  end
end

這是我的模型:( global_Settings.rb

class GlobalSettings < ActiveRecord::Base
  #model validations!
  validates :skey, presence: true
  validates :skey, uniqueness: { case_sensitive: false, message: 'Global setting key     allready exists!'}

  validates :svalue, presence: true        
end

沒有定義視圖或測試或幫助程序!

在rails控制台中如果我這樣做:

gs = GlobalSettings.new(skey: 'testKey', svalue: 'testValue')
D, [2014-11-21T13:11:18.547669 #7215] DEBUG -- :    (192.2ms)  SELECT CAST(1 AS SMALLINT)   FROM RDB$DATABASE
D, [2014-11-21T13:11:18.564272 #7215] DEBUG -- :    (16.3ms)  SELECT CAST(CURRENT_TIMESTAMP   AS TIMESTAMP) FROM RDB$DATABASE
D, [2014-11-21T13:11:18.580900 #7215] DEBUG -- :    (16.4ms)  SELECT CAST(CURRENT_TIMESTAMP AS TIMESTAMP) FROM RDB$DATABASE
#<GlobalSettings skey: "testKey", svalue: "testValue", obs: nil, is_system: true,   created_at: nil, updated_at: nil>
gs.save
D, [2014-11-21T13:11:24.403986 #7215] DEBUG -- :   GlobalSettings Exists (13.2ms)  SELECT    1 AS one FROM "GLOBAL_SETTINGS"  WHERE LOWER("GLOBAL_SETTINGS"."SKEY") = LOWER(?) ROWS 1,   testKey
D, [2014-11-21T13:11:24.543674 #7215] DEBUG -- :   SQL (89.4ms)  INSERT INTO   "GLOBAL_SETTINGS" ("CREATED_AT", "SKEY", "SVALUE", "UPDATED_AT") VALUES (?, ?, ?, ?), 2014-  11-21 13:11:24, testKey, testValue, 2014-11-21 13:11:24
true

正如你所看到的那樣,AR似乎試圖獲取我的模型/表的默認值,在這種情況下,這是不需要的,因為它查詢數據庫3次,它應該只進行插入,並讓SQL發動機照顧其余的。 我該如何防止這種情況發生?

有沒有辦法阻止AR獲取列的默認值?

另一個問題,在GlobalSetting模型的新方法中,我只使用列sKey:sValue:為什么活動記錄將所有其他列放入插入?

AFAIK:new僅創建一個模型對象,該對象接受散列作為參數,其中鍵是您的表屬性。 它此時不會查詢數據庫。 一旦調用save方法,它首先調用有效? 檢查對象是否通過了已定義的驗證的方法。 除了您在此處定義的唯一性驗證外,它獨立於數據庫模式。 唯一性驗證查詢數據庫以檢查此類值是否已存在。 一旦您的對象通過了所有驗證,它就會調用查詢將數據插入到您的數據庫中。 如果數據違反了數據庫級別的某些條件,則會引發異常。 因此,當查詢在數據庫級別運行時,您無法從rails控制它。 如果數據庫中有默認值,則會分配它們。 繞過它們的唯一方法是將一些其他值顯式傳遞給相應的屬性。 並且根據t.timestamps的行為,是的,每當您在創建新記錄時修改該記錄和created_at列時,rails將自動更新updated_at列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM