ROR:如何处理“未能破坏记录”的执行?

时间:2017-04-27 09:30:42

标签: ruby-on-rails activerecord associations

当我用一个答案来陈述一个陈述时会出现错误(并在flash中显示)。

但是当我尝试用这个语句删除测试时,它会上升“无法破坏记录”。

class Test < ActiveRecord::Base
  has_many :statements, dependent: :destroy
  has_many :answers, through: :statements

class Statement < ActiveRecord::Base
  belongs_to :test
  has_many :answers, dependent: :restrict_with_error

我需要:

  • 当语句和语句没有时,将被销毁 有答案。
  • 如果有声明并且任何声明都有答案,请测试不要销毁。
像这样的Smth:

class Test < ActiveRecord::Base
      has_many :statements, dependent: :destroy
      has_many :answers, through: :statements, dependent: :restrict_with_error

我的方法:

test_controller.rb

def destroy
    if @test.destroy
      redirect_to tests_path, notice: 'Good'
    else
      redirect_to tests_path, error: 'Bad'
    end
end

我的方法引发错误:

>> @test.destroy
!! #<ActiveRecord::RecordNotDestroyed: Failed to destroy the record>

1 个答案:

答案 0 :(得分:1)

现在你的问题更清楚了:

您的代码应该已经正常工作,因为我刚刚使用相同的模型进行了测试。但是,我的猜测只是当你破坏一个有答案的语句的测试时,你没有得到flash消息?然后,也许你没有正确设置flash消息错误,见下文。

# models/test.rb
class Test < ActiveRecord::Base
  has_many :statements, dependent: :destroy
  has_many :answers, through: :statements

# models/statement.rb
class Statement < ActiveRecord::Base
  belongs_to :test
  has_many :answers, dependent: :restrict_with_error

# controllers/tests_controller.rb
def destroy
  @test = Test.find(params[:id])

  puts @test.errors.full_messages
  # => nil

  if @test.destroy
    puts @test.errors.full_messages
    #=> nil

    redirect_to tests_path, notice: 'Test was successfully destroyed.'

  else
    puts @test.errors.full_messages
    #=> nil

    @test.statements.each do |statement|
      puts statement.errors.full_messages
      # => ["Cannot delete record because dependent answers exist"]

      statement.errors.full_messages do |full_message|
        @test.errors.add(:base, "statement(id: #{statement.id}): #{full_message}")
      end
    end

    puts @test.errors.full_messages
    # => ["statement(id: 1): Cannot delete record because dependent answers exist"]


    redirect_to tests_path, alert: @test.errors.full_messages
  end
end

测试

检查我的测试是否正确反映了我对您问题的理解:

如果有具有答案的声明<:strong>

,则不应销毁测试
irb(main):001:0 > test = Test.create!
irb(main):002:0 > statement = Statement.create!(test: test)
irb(main):003:0 > answer = Answer.create!(statement: statement)
irb(main):004:0 > test_that_has_statement_that_has_answer = test
irb(main):005:0 > test_that_has_statement_that_has_answer.destroy
=> false
irb(main):006:0 > puts test.persisted?
=> true
irb(main):007:0 > puts test_that_has_statement_that_has_answer.errors.full_messages
=> nil
irb(main):008:0 > puts test_that_has_statement_that_has_answer.statements.first.errors.full_messages
=> ["Cannot delete record because dependent answers exist"]

应该在没有答案的语句时销毁测试:

irb(main):001:0 > test = Test.create!
irb(main):002:0 > statement = Statement.create!(test: test)
irb(main):003:0 > test_that_has_statement_that_has_no_answer = test
irb(main):004:0 > test_that_has_statement_that_has_no_answer.destroy
=> #<Test id: 1...>
irb(main):005:0 > puts test.persisted?
=> false
irb(main):006:0 > puts test_that_has_statement_that_has_no_answer.errors.full_messages
=> nil
irb(main):007:0 > puts test_that_has_statement_that_has_no_answer.statements.count
=> 0
# count becomes 0 which means the statement is automatically destroyed as well