Ruby, как получить исходный объект по его адресу в памяти или по object_id? - PullRequest
0 голосов
/ 27 июня 2018

Например, адрес это строка "0x007f6f0954e820", как получить реальный объект?

Я пишу это: в GymsController

class GymsController < ApplicationController
  @@gyms = Array.new
  def private_page
    ...
    cookies.permanent[:gyms] = JSON.generate(@@gyms << @page)
  end
end

и в history.html.slim

- content_for :title, "History"
- breadcrumb :history
= stylesheet_link_tag 'application'

.outer
  main.privacy-index
    .content-wrapper
      h1.headline2 History一覧
      - JSON.parse(cookies.permanent[:gyms]).reverse.each do |value|
        = (value.to_s.split(":").last)[0..-2].inspect
        br

(value.to_s.split(":").last)[0..-2].inspect - это "0x007f6f2b587b30" Но я хочу получить реальный объект, и мне нравится value.title, value.images

1 Ответ

0 голосов
/ 27 июня 2018

Я не знаю, как "получить" Объект по адресу памяти (т. Е. Вашему 0x007f6f2b587b30),

, но вы можете «получить» Объект с помощью object_id, используя ObjectSpace._id2ref(OBJECT_ID):

Решение:

Важно: это все еще имеет проблемы наследования: см. Мои рекомендации ниже, почему.

приложение / контроллеры / gyms_controller.rb:

class GymsController < ApplicationController
  @@gyms = Array.new
  def private_page
    ...
    gym = @page
    @@gyms << gym
    cookies.permanent[:gyms_object_ids] = gym.object_id
  end
end

ваш файл просмотра:

- content_for :title, "History"
- breadcrumb :history
= stylesheet_link_tag 'application'

.outer
  main.privacy-index
    .content-wrapper
      h1.headline2 History一覧
      - cookies.permanent[:gyms_object_ids]).reverse.each do |gym_object_id|
        - gym = ObjectSpace._id2ref(gym_object_id.to_i)
        = gym.title
        = gym.images
        br

Рекомендации:

  • использовать «переменную экземпляра класса» @gyms вместо «переменная класса класса» @@gyms. Узнайте, почему здесь .

  • , если ваша переменная @page, указанная выше в вашем контроллере, не является записью (поскольку она не соответствует ни одной из ваших моделей и, следовательно, не сохраняется в БД), то создайте модель для этого, чтобы вы могли сохранить его в БД и получить эти данные в ваших представлениях выше через запись модели id, и, следовательно, больше не object_id.

    Это позволит вам решить следующие проблемы моего решения выше:

    • Объекты находятся в памяти и подлежат сборке мусора. Следовательно, использование ObjectSpace._id2ref(OBJECT_ID) иногда может привести к сбою, если объект уже собран мусором. ( см. Это SO ), потому что ObjectSpace._id2ref выше в моем коде решения выполняется с кодом выполнения, отличным от того, где объект был первоначально определен:

      • один находится в контроллере, где определен @page объект (некоторый запрос1 / скажем, поток1),
      • другой находится в файле представления, где ObjectSpace._id2ref() пытается получить этот объект (некоторый запрос2 / скажем, поток2),
    • в вашем коде вы используете @@gyms = Array.new, что означает, что @@gyms (хранящийся в памяти) не будет доступен другим процессам rails, поскольку память не распределяется между этими процессами и «просто» означает, что @@gyms будет иметь РАЗЛИЧНЫХ! значений для каждого из следующих процессов:

      • rails server # 1 (скажем ... единорог-1 в server1)
      • rails server # 2 (скажем ... единорог-2 в server1)
      • rails server # 3 (скажем ... единорог-3 в server2)
      • фоновый рабочий процесс # 1 (скажем ... sidekiq-1)
      • фоновый рабочий процесс # 2 (скажем ... sidekiq-2)
      • и т.д ...

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

      class Gym < ApplicationRecord
        has_many :gyms_users
        has_many :users, through: :gyms_users
      end
      
      class GymsUser < ApplicationRecord
        belongs_to :gym
        belongs_to :user
        validates :user, uniqueness: { scope: :gym }
      end
      
      class User < ApplicationRecord
        has_many :gyms_users
        has_many :gyms, through: :gyms_users
      end
      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...