Использование обратных вызовов для вставки в таблицу при изменении столбца в другой таблице - PullRequest
0 голосов
/ 28 января 2020

У меня есть таблица USERS, в которой хранится количество входов пользователя в систему, а также IP-адрес, который они использовали, и метка времени (из устройства). Я хочу отслеживать sign_in_count и всякий раз, когда он увеличивается, я хочу создать новую запись в другой таблице, которая имеет идентификатор пользователя, его ip и метку времени. Я посмотрел в ActiveModel: грязный модуль (https://api.rubyonrails.org/classes/ActiveModel/Dirty.html), но не уверен, как это реализовать.

Ответы [ 2 ]

0 голосов
/ 28 января 2020

Devise имеет встроенный отслеживаемый модуль :

Отслеживание информации о вашем входе пользователя. Отслеживает следующие столбцы:

  • sign_in_count - Увеличивается каждый раз, когда выполняется вход (по форме, openid, oauth)
  • current_sign_in_at - Отметка времени обновляется, когда пользователь выполняет вход в
  • last_sign_in_at - Содержит отметку времени предыдущего входа в
  • current_sign_in_ip - удаленный ip обновляется при входе пользователя в систему
  • last_sign_in_ip - содержит удаленный ip предыдущего знака в

Это, безусловно, самый простой и лучшее решение, если оно соответствует вашему случаю использования. Если вам нужна связь один ко многим, которая отслеживает все входы пользователей в систему, вы хотите настроить контроллер, а не создавать обратный вызов модели. (подсказка: Обратные вызовы модели - это запах кода ).

class User < ApplicationRecord
  # ...
  has_many :sign_ins
end
class SignIn < ApplicationRecord
  # ...
  belongs_to :user
end
class MySessionsController < Devise::SessionsController
  def create
    super do |user|
      user.sign_ins.create(
        ip_address: request.remote_ip
      )
    end
  end
end
# routes.rb
devise_for :user, controllers: { sessions: 'my_sessions' }

Это фактически удовлетворит все ваши требования:

  • sign_in_count - это количество строк в объединяемой таблице.
  • последний знак - это столбец created_at последней строки для идентификатора пользователя.
  • хранит запрос ip.

Вы могли бы фактически комбинировать его с отслеживаемым, если вам по какой-то причине нужно было хранить все входы в ip вместе, но при этом иметь легкий доступ к последним входным данным в таблице пользователей.

0 голосов
/ 28 января 2020

По моему мнению, у вас есть правильная идея использовать обратный вызов, вот как это можно реализовать.

class User < ApplicationRecord

  after_save :track_sign_in_count



  private

  def track_sign_in_count
    if sign_in_count_changed?
      OtherTable.create!()
    end
  end

end

Я использую обратный вызов after_save, который будет срабатывать каждый раз, когда пользователь запись обновлена ​​или создана. Однако мы использовали встроенный метод sign_in_count_changed?, поэтому он создаст новую запись в OtherTable, только если sign_in_count действительно изменился.

Внутри обратного вызова вы можете использовать self, чтобы получить модель, которая обновляется или создается, так что вы можете получить из нее другие атрибуты, такие как отметки времени или все, что вам нужно.

Примечание: если sign_in_count не изменяется при создании исходной пользовательской записи, вы можете измените обратный вызов на after_update, чтобы он выполнялся только тогда, когда запись пользователя обновлена ​​и не создана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...