【问题标题】:Can't delete record through Rails无法通过 Rails 删除记录
【发布时间】:2012-09-26 22:42:53
【问题描述】:

我有一张桌子,比如 Persons,如果有的话

person = Person.find(:first)
person.delete

我明白了

NoMethodError: undefined method `to_sym' for nil:NilClass
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activesupport-3.1.1/lib/active_support/whiny_nil.rb:48:in `method_missing'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1403:in `block in expand_hash_conditions_for_aggregates'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1402:in `each'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/base.rb:1402:in `expand_hash_conditions_for_aggregates'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/relation/query_methods.rb:261:in `build_where'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/relation/query_methods.rb:124:in `where'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/relation.rb:380:in `delete'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/base.rb:442:in `delete'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/persistence.rb:72:in `delete'
        from (irb):60
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/railties-3.1.1/lib/rails/commands/console.rb:45:in `start'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/railties-3.1.1/lib/rails/commands/console.rb:8:in `start'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/railties-3.1.1/lib/rails/commands.rb:40:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'

如果我这样做了

person.destroy

我明白了

  SQL (0.2ms)  BEGIN
Could not log "sql.active_record" event. NoMethodError: undefined method `name' for nil:NilClass
Mysql::Error: Unknown column 'persons.' in 'where clause': DELETE FROM `persons` WHERE `persons`.`` = ?
   (0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'persons.' in 'where clause': DELETE FROM `persons` WHERE `persons`.`` = ?
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:883:in `prepare'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:883:in `exec_stmt'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:490:in `block in exec_delete'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:244:in `block in log'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activesupport-3.1.1/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract_adapter.rb:239:in `log'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/mysql_adapter.rb:489:in `exec_delete'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:101:in `delete'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `delete'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/relation.rb:351:in `delete_all'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/persistence.rb:94:in `destroy'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/locking/optimistic.rb:119:in `destroy'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/callbacks.rb:254:in `block in destroy'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activesupport-3.1.1/lib/active_support/callbacks.rb:390:in `_run_destroy_callbacks'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activesupport-3.1.1/lib/active_support/callbacks.rb:81:in `run_callbacks'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/callbacks.rb:254:in `destroy'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:236:in `block in destroy'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:208:in `transaction'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
        from .rvm/gems/ruby-1.9.2-p320@rails-3.1.1/gems/activerecord-3.1.1/lib/active_record/transactions.rb:236:in `destroy'
        from (irb):61

但是如果我写一个 SQL 删除语句,我可以通过 MySQL 控制台删除记录。知道会发生什么吗?

其他信息: Person 表有一个 id 列,但数据库中的主键是使用 id 和其他一些列的复合键。 person 模型是别人写的,写了很多方法,但是没有一个名为 delete 或 destroy 的方法被显式写出来。

【问题讨论】:

  • persons 表中有id 列吗?我们还能看到Person 模型吗?
  • @AnthonyAlberto,我在问题中更新了一些内容。还有哪些信息会有所帮助?

标签: mysql activerecord ruby-on-rails-3.1 destroy


【解决方案1】:
@person = Person.first
@person.destroy

如果你使用了非标准的主键,你需要先设置它:

Person.primary_key = 'person_id'
@person = Person.first
@person.destroy

如果一切都失败了……我觉得输入这个很糟糕:

Person.connection.execute("delete from persons where id = 1 and state_id = 2 and project_id = 5")

为了避免当前和未来的噩梦,您应该重组数据库以遵循 Rails 存储数据的标准方式。人员表应仅包含具有唯一 id 列的唯一人员,该列是主键。应该创建新的 project_assignments 表/模型来处理具有自己唯一 ID 以及 state_id、project_id 和 person_id 的分配。属于 Person 的数据应驻留在该表中,分配数据应移动到 project_assignments 等。

【讨论】:

  • 它有一个复合主键。在这种情况下删除记录的最简单方法是什么?
  • 您没有唯一标识个人记录的单列?为什么?您的复合键列是什么?
  • 我在解释,但是像 (id, state_id, project_id) 这样的东西是主键。
  • 你说你在persons表中有相同id列的记录? id 1 = 弗兰克,id 1 = 鲍勃?或者即使您使用复合键,ID 仍然是唯一的?或者你在同一张表中是否有同一个人不同项目的记录?
  • 我对不同的人有相同的 id,比如你的例子。当然,总的复合键是不同的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 2016-09-27
  • 1970-01-01
相关资源
最近更新 更多