I have a Rails model called Tasks
, which has just one attribute: resource_id
. This refers to the ID of a Resource
(another model) on another Rails website running on a different URL with a different database.
When you request a Resource
(e.g. http://localhost:3020/resources/23.json
), it returns the resource in JSON format, for example:
{
"title": "Hello",
"description": "Lorem ipsum..."
}
I want to be able to refer to the requested resource from my current Rails website (the one with the Task
) as such:
# returns a Task with `resource_id: 23`
@task = Task.find(1)
# refers to the Resource from the other Rails server
@task.resource.title
How can I make Rails get the Resource
at the same time it finds the Task
from the local database?
I tried making a resource
attribute in task.rb
which requests the Resource
when it's called as such:
require 'net/http'
class Task < ApplicationRecord
def resource
res = Net::HTTP.get(URI.parse('http://localhost:3020/resources/' + resource_id.to_s + '.json'))
JSON.parse(res)
end
end
However, this runs every time I call task.resource
which is very slow. Can I just request the Resource
once and store it locally in some sort of pseudo-attribute (I don't know what it's called)?
Query all content of external database table not is a efficient. But you can add a caching for your controller:
for example, you can use caching with redis:
require 'net/http'
class Task < ApplicationRecord
def resource
res = $redis.fetch(:resource, expires_in: 1.hour) do
Net::HTTP.get(URI.parse('http://localhost:3020/resources/' + resource_id.to_s + '.json'))
JSON.parse(res)
end
end
end