Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.12 KB | None | 0 0
  1. # Есть класс, проверяющий пользовательские ответы(AnswerCheck). Этот класс при переходе на стейт checked вызывает 3 метода (1). Все три метода обновляют другой класс - UserAnswer. У класса UserAnswer есть колбек на вызов метода award_xp (3), который вызывается, если в сохраненных изменениях прилетает изменение поля solved на любое значение, кроме nil (2). Методы make_user_answer_solved и calculate_points отрабатывают, поле solved y useranswer, привязанного к этому "проверятору" меняется на true, но коллбек не вызывается. Опытным путем было выявлено, что метод calculate_points по какой-то причине перетирает saved_changes, которые приходят с вызовом первого метода make_user_answer_solved. Поэтому изменения применяются, но по итогу после коммита в базу saved_changes остаются только от второго метода, поэтому коллбек и не срабатывает. Вопрос: почему так? Решили тем, что убрали метод calculate_points из коллбека после транзакции и запихнули его внутрь make_user_answer_solved, убрав при этом два апдейта, вот так:
  2. # make_user_answer_solved
  3. #   user_answer.solved = true
  4. #   calculate_points
  5. # end
  6. #
  7. # Вопрос: почему так происходит?
  8.  
  9. class AnswerCheck < ActiveRecord::Base
  10.   belongs_to :user_answer, inverse_of: :answer_check
  11.  
  12.   after_update :calculate_points, if: -> { saved_change_to_attribute?(:teacher_points) }
  13.  
  14.   state_machine :state, initial: :waiting do
  15.     state :waiting
  16.     state :in_queue
  17.     state :checking
  18.     state :checked
  19.  
  20.     event :enqueue do
  21.       transition :waiting => :in_queue, unless: :admin_id?
  22.       transition :waiting => :checking, if: :admin_id?
  23.     end
  24.  
  25.     event :start do
  26.       transition :in_queue => :checking, if: :admin_id?
  27.     end
  28.  
  29.     event :reject do
  30.       transition :checking => :waiting
  31.     end
  32.  
  33.     event :done do
  34.       transition :checking => :checked
  35.       transition :checked => :checked
  36.     end
  37.    
  38.     # 1
  39.     after_transition any => :checked, do: [:make_user_answer_solved, :calculate_points, :update_checking_days_count]
  40.   end
  41.  
  42.   private
  43.  
  44.   def make_user_answer_solved
  45.     user_answer.update!(solved: true)
  46.   end
  47.  
  48.   def calculate_points
  49.     user_answer.set_points
  50.     user_answer.save!
  51.   end
  52.  
  53.   def update_checking_days_count
  54.     update!(checking_days_count: (Time.zone.today - checking_started_at.to_date).to_i)
  55.   end
  56.  
  57. end
  58.  
  59. class UserAnswer < ActiveRecord::Base
  60.   #2
  61.   after_commit :award_xp, unless: -> { saved_changes['solved'].nil? }
  62.  
  63.   #3
  64.   def award_xp
  65.     # Что-то делает этот метод
  66.   end
  67. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement