ruby Rails has_one关联即使在事务回滚[关闭]后也会保存

wgx48brx  于 2023-10-17  发布在  Ruby
关注(0)|答案(2)|浏览(137)

**已关闭。**此问题需要debugging details。它目前不接受回答。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答这个问题。
上个月关门了。
Improve this question
我正在将Rails 3应用程序升级到Rails 5版本。我有一个属于协会的会员。我正在交易块中保存记录。在Rails 5中,我观察到,如果事务被回滚,则空数据被插入到“tasks”表中。在轨道3的情况下,这不会发生。这是Rails 5中的预期行为吗?我不想破坏现有的功能,所以有办法在Rails 5中保留Rails 3的行为吗?
下面是生成此问题的示例代码。

class Student < ApplicationRecord
    has_one :task
end

class Task < ApplicationRecord
    belongs_to :student
    validates_presence_of :name
end

student = Student.first
student.name = nil
def student.testing
 begin
  ActiveRecord::Base.transaction do
   t = Task.new
   t.name = 'ddd'
   t.student = self
   t.save!
   puts "raising exception"
   raise "exception"
  end
 rescue => e
 end
end
student.testing
student.save!
ijxebb2r

ijxebb2r1#

从这个例子中,我只能找出一个问题,那就是rails如何检测inverse_of的关联。

有一个

class Task < ApplicationRecord
  belongs_to :student
end

class Student < ApplicationRecord
  has_one :task, dependent: :destroy
end
>> Task.reflect_on_association(:student).inverse_of.name
=> :task

由于inverse_of已设置,因此当您将student分配给task.student时,逆值也会被分配给-student.task

student = Student.first

student.association(:task).target    #=> nil
Task.new(student: student)
student.association(:task).target    #=> #<Task:0x00007f2333a18ad0 id: nil, name: nil, student_id: 2>

# something to save ---------------------^
student.save!

# INSERT INTO "tasks" ("name", "student_id") VALUES (?, ?)  [["name", nil], ["student_id", 2]]

如果你回滚任务事务,对象仍然被分配给student.task,并且当父对象被保存时,新的关联被保存。这是完全相同的事情:

student = Student.first
Task.transaction do
  Task.create!(student: student)
  raise ActiveRecord::Rollback
end
student.save!

TRANSACTION (0.1ms)  begin transaction
Task Create (0.2ms)  INSERT INTO "tasks" ("name", "student_id") VALUES (?, ?)  [["name", nil], ["student_id", 2]]
TRANSACTION (0.1ms)  rollback transaction
TRANSACTION (0.0ms)  begin transaction
Task Create (0.1ms)  INSERT INTO "tasks" ("name", "student_id") VALUES (?, ?)  [["name", nil], ["student_id", 2]]
TRANSACTION (9.8ms)  commit transaction

无逆

class Task < ApplicationRecord
  belongs_to :student, inverse_of: false
end

has_many相同:

Task.reflect_on_association(:student).inverse_of #=> nil
student = Student.first

student.association(:task).target    #=> nil
Task.new(student: student)
student.association(:task).target    #=> nil

# nothing to save -----------------------^
student.save!

class Task < ApplicationRecord
  belongs_to :student
end

class Student < ApplicationRecord
  has_many :tasks, dependent: :destroy
end
Task.reflect_on_association(:student).inverse_of # => nil
student = Student.first

student.association(:tasks).target    #=> []
Task.new(student: student)
student.association(:tasks).target    #=> []

# nothing to save ------------------------^
student.save!

与逆

class Task < ApplicationRecord
  belongs_to :student, inverse_of: :tasks
end
Task.reflect_on_association(:student).inverse_of.name #=> :tasks
student = Student.first

student.association(:tasks).target    #=> []
Task.new(student: student)
student.association(:tasks).target    #=> [#<Task:0x00007f007d82b2c8 id: nil, name: nil, student_id: 2>]

# something to save ----------------------^
student.save!

# INSERT INTO "tasks" ("name", "student_id") VALUES (?, ?)  [["name", nil], ["student_id", 2]]
qgelzfjb

qgelzfjb2#

假设“belongs_to表”是students(为什么不直接说“students”或“tasks”呢?)那么是的,您显示的代码应该会导致“null data”被保存到students表中。
不知道为什么你会认为围绕Task#save!代码的回滚事务块会影响student.name = nil; student.save!代码?

相关问题