Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Есть класс, проверяющий пользовательские ответы(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, убрав при этом два апдейта, вот так:
- # make_user_answer_solved
- # user_answer.solved = true
- # calculate_points
- # end
- #
- # Вопрос: почему так происходит?
- class AnswerCheck < ActiveRecord::Base
- belongs_to :user_answer, inverse_of: :answer_check
- after_update :calculate_points, if: -> { saved_change_to_attribute?(:teacher_points) }
- state_machine :state, initial: :waiting do
- state :waiting
- state :in_queue
- state :checking
- state :checked
- event :enqueue do
- transition :waiting => :in_queue, unless: :admin_id?
- transition :waiting => :checking, if: :admin_id?
- end
- event :start do
- transition :in_queue => :checking, if: :admin_id?
- end
- event :reject do
- transition :checking => :waiting
- end
- event :done do
- transition :checking => :checked
- transition :checked => :checked
- end
- # 1
- after_transition any => :checked, do: [:make_user_answer_solved, :calculate_points, :update_checking_days_count]
- end
- private
- def make_user_answer_solved
- user_answer.update!(solved: true)
- end
- def calculate_points
- user_answer.set_points
- user_answer.save!
- end
- def update_checking_days_count
- update!(checking_days_count: (Time.zone.today - checking_started_at.to_date).to_i)
- end
- end
- class UserAnswer < ActiveRecord::Base
- #2
- after_commit :award_xp, unless: -> { saved_changes['solved'].nil? }
- #3
- def award_xp
- # Что-то делает этот метод
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement