[英]Passing values from a Ruby on Rails controller into Javascript to render
[英]Efficiently drawing values from joined tables in Ruby on Rails for use in javascript
我已經看到了一些關於我的問題的相關問題,但沒有任何內容完全涵蓋我需要的內容。 我們有3個數據庫表,在我們的javascript中需要訪問的展位上拆分數據。 我將提取此數據以將其轉換為javascript對象數組。 我遇到的問題是嘗試在這3個表之間執行聯接,然后以不會浪費太多資源的有效方式將某些值推入對象。 我的3個對象在這里列出 。 我對RoR還不是很熟悉,所以我先在SQL中寫出了我的查詢:
SELECT b.BoothNumber, bt.Width, bt.Depth, bl.room_id, bl.x, bl.y
FROM Booths b
LEFT JOIN booth_types bt ON bt.id = b.booth_type_id
JOIN booth_locations bl ON bl.id = b.booth_location_id
WHERE bl.room_id = @room_ID_provided_by_javascript
我可以在JS中做最后一行,但是為了清楚起見,我將其包括在內。 什么是我最好的選擇? 我的第一次嘗試看起來像下面的代碼。 當然,它不起作用,因為room_id /等。 不屬於“ booth”對象。
<% Booth.includes(:booth_location, :booth_type).find_each do |booth| %>
if(roomIds.indexOf(<%= booth.room_id%>) > -1){//If index in roomIds (is this room in the event?)
booths.push({boothId: <%= booth.id %>, roomId: <%= booth.roomId %>, x: <%= booth.x %>, y: <%= booth.y %>,
boothNumber: <%= booth.boothNumber %>, companyId: <%= booth.companyId %>, width: <%= booth.width %>, depth: <%= booth.depth %>});
}
<% end %>
我在控制器中的這些表之間有基本的belongs_to
和has_many
連接,但僅此而已。 我知道我需要在我的控制器中包含某種使用through
關鍵字的方法,但我真的不知道這些應該如何與我的數據庫設置方式保持一致。 我已經看到答案不同,從每個控制器添加20多行到在我的開始Ruby行上寫一些額外的單詞。 什么對我有用?
學習has_many :through
與推動Javascript不同。 MVC的一部分是從HTML中刪除DB邏輯。 它應該在模型中完成(盡管通常也在控制器中完成)。 我有時會在HTML中編寫DB邏輯,但這是一種懶惰的方法。
這是一個解釋has_many :through
的示例:
假設Post表有一個user_id列,Tag表有一個post_id列。 換句話說,一個用戶有很多帖子,每個帖子都有很多標簽。 我們正在嘗試鏈接用戶和標記列,以便我們可以說用戶有很多標記。 我們可以寫下面的關聯:
belongs_to :user
belongs_to :post; has_one :user, through: :post
belongs_to :post; has_one :user, through: :post
has_many :posts; has_many :tags, through: :posts
has_many :posts; has_many :tags, through: :posts
請注意,沒有belongs_to
with through
,您需要使用has_one
。
您可以使用source
選項在命名方面獲得更多靈活性。
class Tag
has_one :post_author, through: :post, source: :author
# if for example "post.author" were used instead of "post.user"
end
這是建立聯接表關聯的最簡單方法。 還有其他更復雜的方法。
像has_many
和belongs_to
這樣的方法正在為你的模型創建一個getter方法。 如果您對ActiveRecord查詢語法感到滿意,則可以自己編寫。
例如:
class User
def tags
Tag.joins(:posts).where("posts.user_id = ?", self.id)
# Make sure this method returns an ActiveRecord_Relation,
# not an array.
end
end
此user
實例方法的行為方式與使用has_one through
定義它的方式相同。 這種方法更具可定制性,但對於簡單的情況, has_one
方法的輸入較少。
還有scopes
的概念,它具有用於編寫這些方法的特定於域的語法。
所以,對於Javascript,我建議稍微改變你的方法。 通過ERB標記將所有數據從Ruby傳遞到Javascript可能會變得難以處理。 在將數據發送到Javascript之前,最好將數據轉換為JSON。 有很多用於將數據轉換為Javascript的Rails助手,例如to_json
。 我將向您展示如何將分層數據集轉換為JSON的示例:
class User
def attributes
super.merge(
posts: self.posts.map(&:attributes),
tags: self.tags.map(&:attributes)
)
end
end
然后我將創建一個控制器方法來響應JSON:
render json: { user: @user.attributes }.to_json
這將構建數據,以便您可以編寫user["posts"]
和user["tags"]
如果你想在帖子中嵌套標簽,即你可以寫user["posts"][0]["tags"]
您也可以覆蓋Post屬性:
class Post
def attributes
super.merge(
tags: self.tags.map(&:attributes)
)
end
end
但是要注意不要引入遞歸。
將Ruby數據傳遞給Javascript的最后一步是使用AJAX進行獲取。
Rails有AJAX的視圖助手,但我個人更喜歡用Javascript / jQuery編寫代碼,而不是用ERB編寫代碼。 有關Javascript方法的一些信息,請參閱此問題 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.