Создание модального экземпляра при обновлении атрибута другого в Rails? - PullRequest
0 голосов
/ 07 апреля 2020

Я создаю приложение Rails, которое имеет модалы Outage, Service, Note и User.

Service имеет логический атрибут is_down. По умолчанию is_down равно false. Когда атрибут обновляется до true, что означает, что служба перестает работать, следует создать Outage и Note с User, automated.

Все это происходит в одном обновлении атрибута is_down. Если Service восстанавливается, отключение остается без изменений, но теперь имеет end_time.

Вот «сюжетная линия»:

Сервисная модель:

class Service < ApplicationRecord
    has_many :outages 
    has_many :notes


    # This is where I'm confused 
    is_down 
        if self.is_down 
            Outage.create(start_time: Time.now, reason: nil)
            Note.create(user_id: 1, entry: "Outage began at #{Time.now}", service_id: self.id)
        end
    end 
end

Модель отключения:

class Outage < ApplicationRecord
    belongs_to :service
    has_many :notes 
    has_many :users, through: :notes

end

Примечание модальное (таблица соединения между Outage и User)

class Note < ApplicationRecord
    belongs_to :outage
    belongs_to :user
end

и моделью пользователя:

class User < ApplicationRecord
    has_many :notes
    has_many :outages, through: :notes
end

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

Вот схема:

 enable_extension "plpgsql"

  create_table "notes", force: :cascade do |t|
    t.text "entry"
    t.boolean "is_public", default: true
    t.bigint "outage_id"
    t.bigint "user_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["outage_id"], name: "index_notes_on_outage_id"
    t.index ["user_id"], name: "index_notes_on_user_id"
  end

  create_table "outages", force: :cascade do |t|
    t.datetime "start_time"
    t.datetime "end_time"
    t.text "reason"
    t.boolean "is_recurring", default: false
    t.string "frequency", default: "None"
    t.bigint "service_id"
    t.index ["service_id"], name: "index_outages_on_service_id"
  end

  create_table "services", force: :cascade do |t|
    t.string "name"
    t.boolean "is_down", default: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  add_foreign_key "notes", "outages"
  add_foreign_key "notes", "users"
  add_foreign_key "outages", "services"
end

Помимо первоначального вопроса об автоматическом создании при обновлении атрибута Service, is_down, это также хороший способ для go о реализовать это?

1 Ответ

0 голосов
/ 07 апреля 2020

Я бы предложил изучить обратные вызовы жизненного цикла для ActiveRecord. Вы можете добавить обратный вызов after_save в свой класс Service, который проверяет, изменилось ли is_down, а затем создать или закрыть Outage

class Service < ApplicationRecord
  has_many :outages
  ...

  after_save :create_or_update_outage, if: is_down_changed?

  ...

  private

  def create_or_update_outage
    if is_down
      outages.create
    else
      outages.where(end_time: nil).last.update(end_time: Time.now)
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...