Search code examples
ruby-on-railsactiverecordnet-http

Request part of a Rails model from URL


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)?


Solution

  • 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