我有幾個資料庫視圖,它們作為REST API端點被暴露出來。目前的實作是,一旦添加了一個視圖,我們就會添加Rails代碼,如
。- 添加新的路由 添加控制器和其他代碼,以查詢回傳json回應的視圖。
這種方法的缺點是我們需要在每次添加資料庫視圖時向應用程式添加代碼,有時這也不是即時的,這是另外一個問題。
是否有一種方法,可能通過使用Meta Programming或其他方法,我們能夠查詢資料庫以獲得視圖串列,并生成必要的路由和代碼以回傳有效的回應。
下面是代碼的相關部分
。namespace :api do
命名空間 :v1 do
[
'leases'。
# 一個新的將進入這里。
]
結束。
end
class Api::V1::LeasesController < Api::V1::ApplicationController
api :GET, '/leases', "檢索分頁井月資料"。
param :authentication_token, String, "用于認證的令牌"。
def index
result = Api::Lease.ransack(params[:q]).result.page(params[:page).per(10000)
渲染json: result.to_json
end
end
class Api::Lease < ExternalRecord
self.table_name = 'View_Leases' #View in External Postgres server
end
謝謝你。
uj5u.com熱心網友回復:
是的,但實際的實作取決于所使用的資料庫。在Postgres上,你可以通過查詢是否有一種方法,可能通過使用Meta編程或其他方法,我們能夠查詢資料庫以獲得視圖串列,并生成必要的路由和代碼以回傳有效的回應。
pg_catalog.pg_views得到一個視圖串列:
pg_views = Arel::Table.new('pg_catalog.pg_views')
query = pg_views.project(:schemaname, :viewname)
.where(
pg_views[:schemaname].in('pg_catalog', 'info_schema').not)
)
結果 = ActiveRecord::Base.connection.execute(query)
# ...
但是,這里需要改變一下框架。視圖是否一定要與它自己的路由相對應,或者你可以創建一個更好的RESTful設計?
例如,如果你是按年/月列出,你可以很容易地設定一個涵蓋它的單一路由:
namespace :api do
命名空間 :v1 do
資源 :leases do
獲取'/leases/by_month/:year/:month',作為: 。 by_month, action: :by_month.
end[/span].
end end
end end
你能用元編程設定一個模型嗎?
絕對可以。Ruby中的類是第一類物件,你可以用Class.new創建它們:
# Setup a base class for shared behavior
class ApplicationView < ActiveRecord::Base
self.abstract_class = true
end。
str = 'Foo'/span>
model = Class.new(ApplicationView) do |klass|
# do your model specific thing here...
end
# Classes get their name by being assigned to a constant[/span]。
ApplicationView.const_set(str, model)
ApplicationView::Foo.all # SELECT * FROM foos;
ActiveRecord和ActiveModel其實并不喜歡匿名類(沒有分配給常量的類),因為它們會根據類的名字做一堆假設。在這里,我們在ApplicationView中嵌套常量只是為了避免命名空間的崩潰。
另一種方法是創建一個包含定義類的代碼的字串,并對其進行評估,這種方法有時會在libary代碼中使用。
您還可以設定一個查詢不同表/視圖的單一模型。
你可以用元編程來設定控制器和視圖(如MVC中)嗎?
是的,但是你不應該需要它。你可以簡單地創建能夠處理各種模型的通用控制器。請記住,一個控制器對應一個模型的想法只是一個慣例,適用于瑣碎的情況。
uj5u.com熱心網友回復:
你可以通過一個給定的連接來進行任意的SQL查詢
namespace :v1 do
資源 :views, only::show
end
class ViewsController
def show
table_name = "View_#{params[:id] .titleize}"
offset = (params[:page].to_i || 1) * 10_000 - 10_000
limit = 10_000 - 10_000
sql = "SELECT #{table_name}. * FROM #{table_name} OFFSET #{offset} LIMIT #{limit}; "/span>
data = ActiveRecord::Base.connection.execute(sql)
渲染json: data.to_json
end
end
但是后來忘記了使用Ransack。Ransack需要一個模型,它依賴于推斷出的列型別,將查詢轉換為模型本身的一系列where、join等。
當然,如果你制作自己的SQL字串,你應該保護自己免受SQL注入。
如果您希望保留查詢的全部功能,您最好在您的應用程式和視圖之間放置類似于Hasura的東西,并將傳入的查詢轉換為對 hasura 的 GraphQL 請求(其將為您處理其余部分)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/307627.html
標籤:
上一篇:NoMethodErrorinArticles#show(undefinedmethod`each'fornil:NilClass)[closed]
