Итак, у меня есть довольно сложная модель, которая использует область действия, чтобы установить 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, я не получаю ошибок. Это кажется неправильным / неаккуратным.
Как точно отобразить для коллекции онлайн-устройства разных моделей?