简体   繁体   English

如何防止Ruby on Rails Active记录从数据库中获取默认模型值?

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

I'm developing a RoR app, with Firebird with its SQL engine but i cant understand why ActiveRecord (AR) keeps querying the database for default values! 我正在开发一个RoR应用程序,Firebird和它的SQL引擎,但我不明白为什么ActiveRecord(AR)一直在查询数据库的默认值!

Here is the tables DDL: 这是表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)
);

Here is the migration that created this table: ( create_global_settings.rb ) 以下是创建此表的迁移:( 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

Here is my model: ( global_Settings.rb ) 这是我的模型:( 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

No views or tests or helper are defined! 没有定义视图或测试或帮助程序!

In rails console if i do: 在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

As you can see it seems that AR is trying to get the default values for my model/table, and in this case that is not needed because it's querying the database 3 times, and it should only be doing an insert, and letting the SQL engine take care of the rest. 正如你所看到的那样,AR似乎试图获取我的模型/表的默认值,在这种情况下,这是不需要的,因为它查询数据库3次,它应该只进行插入,并让SQL发动机照顾其余的。 How do i prevent this kind of situation to happen? 我该如何防止这种情况发生?

Is there any way to prevent AR to fetch defaults for columns? 有没有办法阻止AR获取列的默认值?

And another question, in the new method of the GlobalSetting model i am just using columns sKey: and sValue: , why is active record putting all others columns in the insert? 另一个问题,在GlobalSetting模型的新方法中,我只使用列sKey:sValue:为什么活动记录将所有其他列放入插入?

AFAIK: new only creates a model object which accepts a hash as a parameter in which keys are your table attributes. AFAIK:new仅创建一个模型对象,该对象接受散列作为参数,其中键是您的表属性。 It does not query database at this point of time. 它此时不会查询数据库。 Once you call the save method, it first calls valid? 一旦调用save方法,它首先调用有效? method to check if your object passes the validations you have defined. 检查对象是否通过了已定义的验证的方法。 It is independent of database schema except for the uniqueness validation you have defined here. 除了您在此处定义的唯一性验证外,它独立于数据库模式。 Uniqueness validation queries the database to check if such a value already exists. 唯一性验证查询数据库以检查此类值是否已存在。 Once your object passes all the validations, it then calls the query to insert the data into your database. 一旦您的对象通过了所有验证,它就会调用查询将数据插入到您的数据库中。 If the data violates some conditions at database level, exception is raised. 如果数据违反了数据库级别的某些条件,则会引发异常。 So when the query is run at the database level, you have no control over it from rails. 因此,当查询在数据库级别运行时,您无法从rails控制它。 If there are default values in the database, they'll be assigned. 如果数据库中有默认值,则会分配它们。 The only way to bypass them is to explicitly passing some other values to the corresponding attribute. 绕过它们的唯一方法是将一些其他值显式传递给相应的属性。 And as per the behaviour of t.timestamps, yes, rails will automatically update the updated_at column each time you modify that record and created_at column when you create a new record. 并且根据t.timestamps的行为,是的,每当您在创建新记录时修改该记录和created_at列时,rails将自动更新updated_at列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM