簡體   English   中英

Ruby:使用字符串插值訪問ActiveRecord屬性

[英]Ruby: Use string interpolation to access ActiveRecord properties

我是否可以使用字符串插值來建立ActiveRecord查詢,如下所示:

query = '.owner.name'
widget = Widget.first
name = "#{Widget" + query + "}"

這顯然行不通,但我正在尋找一種可接受的替代方案。

query = '.owner.name'
widget = Widget.first
name = eval "widget#{query}"

並不是說這是一個好主意,但是它確實有效。

“ eval”是否令人討厭?

強大的力量帶來巨大的責任感(和風險)。

由於Rails使用散列將列映射到方法,並且這些散列是“訪問無關的散列”,因此可以使用字符串或符號。 從而:

widget = Widget.first
widget[:owner] # => returns the same as widget.owner
widget['owner'] # => also returns widget.owner. 

上面的代碼的問題在於,所有者可能是另一列的外鍵,因此方法名稱實際上是:

widget['owner_id']

返回一個整數,Rails使用該整數在Owners表中查找ID。 因此,如果僅將返回Widget表中的列的列串在一起,則可以使用上面的代碼。 但是,當將查詢方法串在一起時,通常是因為您正在數據庫中查找某種關系並在其上調用列方法。

因此,您將需要執行某種遞歸循環:

query = 'owner.name'
q = query.split'.'

並完成以下工作:

q0 = "#{q[0]}_id"
q1 = "#{q[1]}"
Owner.find(widget[q0])[q1]

#Owner Load (0.6ms)  SELECT "owners".* FROM "owners" WHERE "owners"."id" = $1 LIMIT 1  [["id", 9]]
#=> "Joe"

因此,從理論上講,您可以將查詢字符串分割成點,然后將“ _id”添加到除最后一個以外的所有其他字符,然后使用(可能嵌套的) .find命令將它們鏈接在一起。 能做到嗎 大概。 應該按照我的描述來做嗎? 可能不是。

如果您提供更具描述性的用例場景,人們可能會提供更好的答案。 從更廣泛的角度來看,您真正想做什么? 可能還有其他方法完全消除了執行您所要詢問的需求。

這是一個不太字符串化的版本。

widget = Widget.first
query = 'owner.name'
name = query.split('.').inject(widget){|sum, meth| sum.send(meth)}

這將隨后用點分隔的方法應用於傳遞到注入的對象。

您甚至可以在模型中將注入調用定義為方法。

但是請注意,如果有人向您的屬性中注入“ class.delete_all”,則所有小部件都將被刪除(同樣適用於其他解決方案)

雖然您可以使用aval並獲得所需的東西,但這並不是解決它的最佳方法。

所以。 如果您希望有條件地追加活動記錄查詢,則應使用合並

作為您的案例的概述(不是最佳示例,但您知道了)

widget = Widget.first
owner = Widget.first.owner

widget_owner = if <some condition>
                  widget.merge(owner)  
               end
widget_owner.try(:name)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM