Рельсы Заказ по Прицелу с Draper / Decorate от другой модели - PullRequest
0 голосов
/ 01 апреля 2020

Итак, у меня есть довольно сложная модель, которая использует область действия, чтобы установить sh, что считается онлайн, а что считается автономным. Затем в моем модуле администратора я отображаю все доступные устройства. То, что я хочу сделать, это заказать тех, кто в настоящее время онлайн.

Итак, модель выглядит следующим образом:

class Device < ActiveRecord::Base
  include Tokenizer

  belongs_to :user
  belongs_to :organization
  belongs_to :former_user, class_name: 'User', foreign_key: 'former_user_id'
  belongs_to :order

  belongs_to :replaced_by_device, class_name: 'Device', foreign_key: 'replaced_by_device_id'
  has_and_belongs_to_many :user_clients, join_table: :user_clients_devices
  has_many :user_client_speed_tests, through: :user_clients
  validates :hardware_token, uniqueness: true, presence: true, length: { maximum: 50 }
  validates :mac, mac_address: true, allow_blank: false, allow_nil: true

  before_validation :generate_hardware_token, on: :create
  before_validation :assign_organization_id_if_missing

  validate :existence_of_user_id, if: :user_id?
  validate :existence_of_organization_id, if: :organization_id?
  validates_numericality_of :user_id, :organization_id, allow_nil: true, greater_than_or_equal_to: 0

  alias_attribute :name, :mac

  scope :with_macs, -> { where("mac IS NOT NULL AND hardware_mac <> ''") }
  scope :without_macs, -> { where("mac IS NULL OR hardware_mac = ''") }
  scope :with_old_macs, -> { where("mac LIKE :prefix", prefix: "C0%") }
  scope :with_new_macs, -> { where("mac LIKE :prefix", prefix: "A%") }
  scope :without_user, -> { where(user_id: nil) }
  scope :with_user, -> { where.not(user_id: nil) }
  scope :online, -> { where("last_seen_at > ?", 1.hour.ago) }
  scope :offline, -> { where.not(id: online.ids) }
  scope :installed_online, -> { installed.online }
  scope :installed_offline, -> { installed.where.not(id: installed_online.ids) }

  enum status: [ :operational, :replaced ]

  after_save :set_provisioned_if_needed

  has_paper_trail

  ransacker :mac_address_presence, formatter: proc{ |value|
    value.eql?('present') ? with_macs.ids : without_macs.ids
  }, splat_params: true do |parent| parent.table[:id] end

  ransacker :mac_address_type, formatter: proc{ |value|
    value.eql?('old') ? with_old_macs.ids : with_new_macs.ids
  }, splat_params: true do |parent| parent.table[:id] end

  ransacker :organization_presence, formatter: proc{ |value|
    value.eql?('present') ? with_organization.ids : without_organization.ids
  }, splat_params: true do |parent| parent.table[:id] end

  ransacker :installation_status, formatter: proc{ |value|
    case value
    when 'installed' then installed.ids
    when 'not_installed' then not_installed.ids
    when 'not_assigned' then not_assigned.ids
    end
  }, splat_params: true do |parent| parent.table[:id] end

  ransacker :connection_status, formatter: proc{ |value|
    data = value.eql?('online') ? online.ids : offline.ids
    data.any? ? data : nil
  }, splat_params: true do |parent| parent.table[:id] end

  ransacker :wifi_signal_strength, formatter: proc{ |value|
    data =  case value
        when 'borderline' then with_borderline_signal_strength.ids
        when 'bad' then with_bad_signal_strength.ids
        when 'ok' then with_ok_signal_strength.ids
        when 'good' then with_good_signal_strength.ids
        else with_great_signal_strength.ids end
data.any? ? data : nil
  }, splat_params: true do |parent| parent.table[:id] end

  def update_status(new_status)
    update!(status: new_status, status_last_changed_at: Time.now.utc)
  end

  def can_replace_hw?
    operational? && (order.nil? || (order.present? && order.completed?))
  end

  def last_user_client
    user_clients.last
  end

  def last_user_client_speed_test
    last_user_client.last_speed_test if last_user_client.present?
  end

  def speed_tests
    user_client_speed_tests
  end
  def has_last_user_client?
    last_user_client.present?
  end

  def has_been_seen?
    has_last_user_client? && last_user_client.last_seen_at.present?
  end

  def offline?
    if has_been_seen?
      last_user_client.last_seen_at < 1.hour.ago
    end
  end

  def online?
    if has_been_seen?
      last_user_client.last_seen_at > 1.hour.ago
    end
  end

  def connection_status_history
    last_seen_history = last_seen_histories.where('last_seen_at > ?', 2.weeks.ago).order(:last_seen_at).to_a
    status_history = []
    while last_seen_history.present?
      next_last_seen = last_seen_history.shift
      status_history << {
          status: "Online",
          timestamp: next_last_seen.last_seen_at.in_time_zone(Time.now.zone)
      }

      if (last_seen_history.first&.last_seen_at || Time.current) - status_history.last[:timestamp] > 1.hour
        status_history << {
            status: "Offline",
            timestamp: status_history.last[:timestamp].in_time_zone(Time.now.zone) + 1.hour
        }
      end
    end

    status_history
  end

end

Тогда в моем представлении администратора у меня есть вход, на который я ссылаюсь:

= f.input :user_device_ids, label: false, as: :select, multiple: true, collection: @organization.available_devices.decorate

Итак, из организации I хочу сделать заказ с помощью онлайн-устройств. Я думал, что смогу сделать что-то вроде @ organization.available_devices.order (онлайн) .decorate. Это явно не помогает, потому что онлайн это сфера устройств, а не из организации. Поэтому, если я делаю что-то вроде @ organization.available_devices.order (Device.online) .decorate, я не получаю ошибок. Это кажется неправильным / неаккуратным.

Как точно отобразить для коллекции онлайн-устройства разных моделей?

1 Ответ

1 голос
/ 01 апреля 2020

При рассмотрении примера кода возникли две вещи:

  1. У вас есть belongs_to :order, который можно легко спутать с методом order ActiveRecord: https://apidock.com/rails/ActiveRecord/QueryMethods/order
  2. Если вы временно удалите belongs_to :order и попробуете @organization.available_devices.order(:last_seen_at, :desc).decorate, все должно работать как положено.

Надеюсь, что это поможет.

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