0

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

10
  • what exactly are you trying to do?? Commented Jun 27, 2018 at 10:00
  • @I wanna save an object array to cookies, like this: cookies[:links] = JSON.generate(@array << @object) But when I do JSON.parse(cookies[:links]).each do |value|, I get some address string. I actually wanna get origin objects. Commented Jun 27, 2018 at 10:02
  • Can you show what you have and what you want to fetch from it? Commented Jun 27, 2018 at 10:06
  • @JagdeepSingh I have that object's obejct_id and its address which is a string. I want to get its origin object. Commented Jun 27, 2018 at 10:10
  • 1
    No, the value of (value.to_s.split(":").last)[0..-2].inspect is "0x007...", but what is the value of variable value? Even before the whole chain of methods is called on it. Commented Jun 27, 2018 at 10:25

1 Answer 1

2

I do not know a way to "get" the Object by memory address (i.e. 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
      
Sign up to request clarification or add additional context in comments.

2 Comments

You are awesome!
No prob! Glad to help! :3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.