【问题标题】:I'm unable to save an activeRecord object in a legacy table using a view我无法使用视图将 activeRecord 对象保存在旧表中
【发布时间】:2012-08-09 16:33:16
【问题描述】:

我在旧数据库中有一个表,其中有一个名为字段的列。 将表直接链接到 activeRecord 模型是不可能的,因为后者会尝试创建方法 field_changed?已经定义好了。

所以我创建了一个视图来重命名字段,并创建了以下规则来允许插入、更新和删除。

create or replace rule new_linked_fields_upd as on update to new_linked_fields 
     do instead 
     update linked_fields set race_id = new.race_id , master_id = new.master_id, field = new.field_name
     where id = new.id;

create or replace rule new_linked_fields_ins as on insert to new_linked_fields
     do instead
     insert into linked_fields select nextval('linked_fields_id_seq'), new.race_id, new.field_name, new.master_id;

create or replace rule new_linked_fields_del as on delete to new_linked_fields
     do instead
      delete from linked_fields where id = old.id;

我将 activeRecord 模型链接到视图。

class LinkedField < ActiveRecord::Base
  self.table_name ="new_linked_fields"
  self.primary_key = "id"
end

我必须添加 self.primary_key = "id",否则 LinkedField.last 等方法会失败(生成错误的 SQL)。

在 SQL 中一切正常。 在 ruby​​ 中,我可以更新 LinkedField 的属性,或者销毁一个实例,但我不能创建一个。

LinkedField.create(field_name:'toto',race_id:-3,master_id:4)

返回以下错误。

   (0.3ms)  BEGIN
  SQL (1.0ms)  INSERT INTO "new_linked_fields" ("field_name", "master_id", "race_id") VALUES ($1, $2, $3) RETURNING "id"  [["field_name", "toto"], ["master_id", 4], ["race_id", -3]]
   (0.3ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::Error: ERROR:  syntax error at end of input
LINE 1: DEALLOCATE
                   ^
: INSERT INTO "new_linked_fields" ("field_name", "master_id", "race_id") VALUES ($1, $2, $3) RETURNING "id"
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:297:in `exec'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:297:in `dealloc'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:287:in `delete'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:1172:in `rescue in exec_cache'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:1155:in `exec_cache'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:665:in `block in exec_query'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.6/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:663:in `exec_query'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb:63:in `exec_insert'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb:90:in `insert'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/relation.rb:66:in `insert'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/persistence.rb:363:in `create'
     from /Users/macbook/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.6/lib/active_record/timestamp.rb:57:in `create'

有什么提示吗?我正在使用 postgres 9.0 和 rails 3.2.6。 谢谢

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord rails-postgresql


    【解决方案1】:

    首先,如果您能够更新到 PostgreSQL 9.1,view triggers 比规则更容易正确。

    其次,DEALLOCATE 来自哪里?它是否试图释放准备好的语句?

    尝试在postgresql.conf 中启用log_statement = 'all',重新加载 PostgreSQL(pg_ctl reloadSIGHUP 邮局管理员,或重新启动它),重新运行测试并检查 Pg 的日志。查看 Rails 程序实际运行的 SQL。

    【讨论】:

    • 谢谢克雷格。 Postgresql 对这个问题给出了明确的解释。错误:无法对关系“new_linked_fields”执行 INSERT RETURNING 提示:您需要一个带有 RETURNING 子句的无条件 ON INSERT DO INSTEAD 规则。
    • 现在的规则是:创建或替换规则 new_linked_fields_ins 就像插入到 new_linked_fields 时一样,而是插入到linked_fields select nextval('linked_fields_id_seq'), new.race_id, new.field_name, new.master_id RETURNING linked_fields。 *;
    • 你知道我是否还必须添加返回值来删除和更新规则吗?到目前为止,一切似乎都正常。
    • @jlfenaux Re RETURNING 关于插入删除和更新规则的子句,这是一个非常有趣的问题。我怀疑是这样,否则要获得行数会很棘手,而且不可能使用DELETE ... RETURNING 查询。请参阅documentation on rules。如果有疑问,请通过psql 在 SQL 级别对其进行测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 2013-09-16
    • 1970-01-01
    • 2015-04-28
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多