简体   繁体   中英

Ruby, how to fetch origin object by its memory address or by object_id?

For example, the address is "0x007f6f0954e820" string, how to get actual object?

I write these: in GymsController

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

and in 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 is "0x007f6f2b587b30" But I wanna get real object, and do like value.title , value.images

I do not know a way to "get" the Object by memory address (ie your 0x007f6f2b587b30 ),

but you can "get" the Object by object_id using ObjectSpace._id2ref(OBJECT_ID) :

Solution:

Important: this still has inherit issues: see my recommendations below why.

app/controllers/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

your view file:

- 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

Recommendations:

  • use "class instance-variable" @gyms instead of "class class-variable" @@gyms . See why here .

  • if your @page variable above in your controller, is not a record (being that it does not correspond to any of the models you have, and thus is not saved in the DB), then create a model for it, so that you can save it into the DB, and retrieve these data in your views above through the model's record id , and therefore no longer by object_id .

    This would allow you to solve the following issues of my Solution above:

    • Objects reside in memory, and are subject to garbage collection. Therefore using ObjectSpace._id2ref(OBJECT_ID) is probably gonna fail at times if the Object is already garbage-collected. ( see this SO ), because ObjectSpace._id2ref above in my solution code runs at different code of execution than where the object is originally defined:

      • one is in the controller where @page object is defined (some request1 / say thread1),
      • the other one is in the view file where ObjectSpace._id2ref() tries to get that object (some request2 / say thread2),
    • in your code, you are using @@gyms = Array.new , which means that @@gyms (being stored in-memory) is not gonna be accessible to other rails processes because memory is not shared between these processes, and to put simply means that @@gyms would have DIFFERENT! values for each of the following processes:

      • rails server #1 (say... unicorn-1 in server1)
      • rails server #2 (say... unicorn-2 in server1)
      • rails server #3 (say... unicorn-3 in server2)
      • background worker process #1 (say... sidekiq-1)
      • background worker process #2 (say... sidekiq-2)
      • etc...

      ...whereas if you instead save the gyms (if possible and if necessary only) into a model and that these gym records belong to a user, then I would imagine doing something like below instead (which will solve these potential differing values above, and will no longer require you to use cookies):

       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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM