[英]Request part of a Rails model from URL
我有一個名為Tasks
的Rails模型,它只有一個屬性: resource_id
。 這是指另一個Rails網站上的Resource
(另一個模型)的ID,該Resource
在具有不同數據庫的不同URL上運行。
當您請求Resource
(例如http://localhost:3020/resources/23.json
)時,它將以JSON格式返回資源,例如:
{
"title": "Hello",
"description": "Lorem ipsum..."
}
我希望能夠這樣引用我當前的Rails網站(帶有Task
網站)中的請求資源:
# returns a Task with `resource_id: 23`
@task = Task.find(1)
# refers to the Resource from the other Rails server
@task.resource.title
如何使Rails從本地數據庫中找到Task
的同時獲取Resource
?
我試圖在task.rb
創建一個resource
屬性,當它這樣調用Resource
時,它會請求Resource
:
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
但是,這每次我調用task.resource
時都會運行,這非常慢。 我能否只請求一次Resource
並將其存儲在某種偽屬性中(我不知道它叫什么)?
查詢外部數據庫表的所有內容不是很有效。 但是您可以為控制器添加緩存:
例如,您可以對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
這是我解決自己的問題的方式:
首先,向Task
添加一個名為resource_string
的字符串屬性。
task.rb
require 'net/http'
class Task < ApplicationRecord
def resource
JSON.parse(resource_string)
end
after_find do |task|
task.resource_string = request_resource task
end
private
def request_resource(task)
Net::HTTP.get(URI.parse('http://localhost:3020/resources/' + task.resource_id.to_s + '.json'))
end
end
然后,您可以按以下方式訪問資源:
@task = Task.find(1)
@task.resource['title']
它只會發出一次請求,並在調用find方法之后將其寫入resource_string
屬性。
您需要向“任務和資源”添加關聯:
在task.rb中:
has_many: :resources
在resource.rb中:
belongs_to: :task
這些關聯會自動將諸如資源方法之類的方法添加到模型中: https : //guides.rubyonrails.org/association_basics.html
然后在您的控制器操作中,使用:includes連接兩個表:
@tasks = Task.includes(:resource)
參見此處: https : //apidock.com/rails/ActiveRecord/QueryMethods/includes
並在此處進行說明: https : //guides.rubyonrails.org/active_record_querying.html#eager-loading-associations
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.