Cra*_*ted 5 ruby firebird ruby-on-rails rails-activerecord
我正在使用Firebird及其SQL引擎开发RoR应用程序,但我不明白为什么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)
);
Run Code Online (Sandbox Code Playgroud)
这是创建此表的迁移:(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
Run Code Online (Sandbox Code Playgroud)
这是我的模型:(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
Run Code Online (Sandbox Code Playgroud)
没有定义视图,测试或帮助器!
在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
Run Code Online (Sandbox Code Playgroud)
如您所见,AR似乎正在尝试获取我的模型/表的默认值,在这种情况下,这是不需要的,因为它要查询数据库3次,并且只应执行插入操作并让SQL引擎负责其余的工作。我如何防止这种情况发生?
有什么方法可以防止AR获取列的默认值吗?
还有一个问题,在GlobalSetting模型的新方法中,我仅使用列sKey:和sValue:,为什么活动记录将所有其他列放入插入中?
AFAIK: new 仅创建一个模型对象,该对象接受哈希作为参数,其中键是表属性。此时它不会查询数据库。一旦调用 save 方法,它首先调用 valid? 方法来检查您的对象是否通过您定义的验证。除了您在此处定义的唯一性验证之外,它独立于数据库模式。唯一性验证查询数据库以检查这样的值是否已存在。一旦您的对象通过了所有验证,它就会调用查询将数据插入到数据库中。如果数据违反数据库级别的某些条件,则会引发异常。因此,当查询在数据库级别运行时,您无法从 Rails 控制它。如果数据库中有默认值,则会分配它们。绕过它们的唯一方法是显式地将一些其他值传递给相应的属性。根据 t.timestamps 的行为,是的,每次您修改该记录时,rails 都会自动更新 Updated_at 列,并在创建新记录时自动更新created_at 列。
| 归档时间: |
|
| 查看次数: |
895 次 |
| 最近记录: |