【问题标题】:Cannot delete record after using Rails default scope with associations使用带有关联的 Rails 默认范围后无法删除记录
【发布时间】:2013-08-28 13:47:17
【问题描述】:

我有表 emailsusersemails 表有两个字段:user_idpublish_id

我使用了这样的默认范围:

default_scope joins('LEFT OUTER JOIN users ON users.id = emails.publish_id').where("users.status IN (?)", ["approve", "spam"])`

由于users 表包含publisherssubscribers,所以我使用users_id 关联subscriberspublish_id 关联publishers

我正在使用以下方法获取记录:

email = Email.unscoped.find(:id)
email.delete

但是,我收到以下错误:

有人可以告诉我如何删除此邮件或如何强制删除删除电子邮件吗?

完整的错误信息:-

 em=Email.unscoped.last
  Email Load (0.5ms)  SELECT `emails`.* FROM `emails` ORDER BY `emails`.`id` DESC LIMIT 1
 => #<Email id: 4, user_id: 2, body: "asdasd", complete_email: {}, created_at: "2013-08-28 15:29:10", updated_at: "2013-08-28 15:29:10", snapshot_status: nil, thumbnail: nil, deleted_at: nil, read: nil, publish_id: 1, email_type: nil, snapshot_thumb_file_name: nil, snapshot_thumb_content_type: nil, snapshot_thumb_file_size: nil, snapshot_thumb_updated_at: nil> 
1.9.3p448 :017 > em.delete
  SQL (0.5ms)  UPDATE `emails` SET `deleted_at` = '2013-08-28 15:29:24' WHERE `emails`.`id` = 4 AND (`emails`.`deleted_at` IS NULL) AND (users.status IN ('approve','spam'))
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.status' in 'where clause': UPDATE `emails` SET `deleted_at` = '2013-08-28 15:29:24' WHERE `emails`.`id` = 4 AND (`emails`.`deleted_at` IS NULL) AND (users.status IN ('approve','spam'))
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `block in execute'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activesupport-3.2.13/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `execute'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:211:in `execute'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:238:in `exec_delete'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:96:in `update'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `update'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/relation.rb:294:in `update_all'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/acts_as_paranoid-0.4.2/lib/acts_as_paranoid/relation.rb:24:in `delete_all'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/relation.rb:442:in `delete'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/querying.rb:7:in `delete'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/activerecord-3.2.13/lib/active_record/persistence.rb:119:in `delete'
    from (irb):17
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /home/awsome/.rvm/gems/ruby-1.9.3-p448@awsome/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'

以下是用户类定义:-

User
 => User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, provider: string, uid: string, name: string, username: string, role: string, photo_file_name: string, photo_content_type: string, photo_file_size: integer, photo_updated_at: datetime, confirmation_token: string, confirmed_at: datetime, confirmation_sent_at: datetime, unconfirmed_email: string, tag_listing: string, status: string, private_publisher: boolean, public_wall_display: boolean, personal_email: string)

【问题讨论】:

  • 是的,我会检查一下,也许会做一个rake db:migrate 以确保您没有任何未完成的迁移。 (还有rake db:test:prepare。)
  • @vinodadhikary,它没有说statususers 表中不存在。它说:where 子句中的未知列。那是完全不同的事情。在不加入 users 表的情况下使用 users.status 时会出现该错误。
  • 正如我上面指出的,它在where 子句中使用users.status,但users 表没有加入。请参阅下面的答案以获取解决方案。

标签: ruby-on-rails ruby-on-rails-3 activerecord activemodel default-scope


【解决方案1】:

您应该像这样使用unscoped block

Email.unscoped do
  email = Email.find(id)
  email.delete
end

或(相同,但更短):

Email.unscoped do
  Email.find(id).delete
end

或者在一个查询中而不是两个:

Email.unscoped do
  Email.where(:id => id).delete_all
end

【讨论】:

  • 不幸的是,上述方法对我不起作用。但是,这确实做到了Email.unscoped.find(id).destroy({:force =&gt; true})
【解决方案2】:

试试

email = Email.unscoped.reload.find(:id)
email.delete

【讨论】:

    猜你喜欢
    • 2022-10-01
    • 2021-11-17
    • 2022-12-18
    • 2016-07-22
    • 2017-09-23
    • 1970-01-01
    • 2017-04-17
    • 2013-05-30
    • 1970-01-01
    相关资源
    最近更新 更多