2017-01-05 10 views
0

Я использую Rails 5. Я хочу, чтобы метод вызывался на моей модели только тогда, когда модель была впервые создана. Я попытался это ...Как вызвать метод только тогда, когда мой объект (модель) сначала создается в Rails 5?

class UserSubscription < ApplicationRecord 

    belongs_to :user 
    belongs_to :scenario 

    def self.find_active_subscriptions_by_user(user) 
    UserSubscription.joins(:scenario) 
     .where(["user_id = ? and start_date < NOW() and end_date > NOW()", user.id]) 
    end 

    after_initialize do |user_subscription| 
    self.consumer_key = SecureRandom.urlsafe_base64(10) 
    self.consumer_secret = SecureRandom.urlsafe_base64(25) 
    end 

end 

, но я заметил это вызывается каждый tiem я извлечение модели из метода поиска в дополнении к его начать создан. Как создать такую ​​функциональность в моей модели?

+0

Вы можете заменить этот метод поиска областью видимости: 'scope: active_subscriptions_by_user, -> (пользователь) {где (" user_id =? И start_date NOW() ", user.id)} ' – mysmallidea

ответ

0

Вы хотите использовать after_create (от active record docs) или after_create_commit, который был введен в Rails 5 в качестве ярлыка для after_commit :hook, on: :create.

after_create всегда выполняется после блока транзакций, тогда как after_create_commit делает это после фиксации, но в пределах того же блока транзакций. Эти данные, вероятно, не имеют значения здесь, но это новая возможность, если вам нужен дополнительный контроль для обеспечения правильности состояния модели перед тем, как выполнить последующий вызов.

+0

Спасибо. Означает ли это, что after_create выполняется до того, как объект будет сохранен в db? В основном я пытаюсь установить значения для объекта, потому что они не будут существовать, когда объект изначально будет создан. et, я не хочу прикасаться к ним. –

+0

'after_create' выполняется после сохранения объекта в db. 'before_create' выполняется до того, как объект будет сохранен в db. – Pyrce

0

Ответ Пирса - это хорошо. Другой способ, чтобы сохранить метод after_initialize, но только работать, если это новый рекорд:

after_initialize :set_defaults 
def set_defaults 
    if self.new_record? 
    self.consumer_key = SecureRandom.urlsafe_base64(10) 
    self.consumer_secret = SecureRandom.urlsafe_base64(25) 
    end 
end 

(Это обычно считается лучше не переопределить метод after_initialize Вместо указать имя метода для запуска, как я сделал выше. .