簡體   English   中英

理解Rails中與ActiveRecord的關系

[英]Understanding Relational with ActiveRecord in Rails

我理解SQL我理解數據庫方法我理解Rails我不懂ActiveRecord關系

我有三個模型(簡化),我用rails g模型創建,然后執行rake db:使用mysql db進行遷移。

Calendar
id: number
name: string

Event
id: number
title: string

Event_Tag
id: number
event_id
key: string
value: string

我如何對所有事件執行查詢並檢索每個事件的所有event_tags,以便我可以用最少的查詢構建JSON模型?

Event
id: number
title: string
tags: [
    <key>:<value>,
    <key>:<value>,
    <key>:<value>,
]

我試過這個:

events = Event.includes(:event_tag).where("events.calendar_id" => params[:calendar_id])

我所見,避免了N + 1查詢問題。 它執行2個查詢。

Event Load (47.1ms)  SELECT `events`.* FROM `events`  WHERE `events`.`calendar_id` = 1

EventTag Load (46.3ms)  SELECT `event_tags`.* FROM `event_tags`  WHERE `event_tags`.`event_id` IN (1) 

但是,當我檢查一個事件

eventHash = events[0]

我收到

#<ActiveRecord::Relation [#<Event id: 1, title: "Test", calendar_id: 1, created_at: nil, updated_at: nil>]>

ActiveRecord的

雖然我不知道ActiveRecord的幕后工作,但我知道這就是所謂的ORM(對象相關映射)系統 (SQL框架)

這意味着它為您提供了一系列調用方法,然后將其轉換為相關的SQL查詢( joins等)


協會

ActiveRecord關聯基本上是美化的join語句 - 每次調用一個對象,然后引用它的關聯數據,你基本上會調用兩個查詢來ping兩個單獨的數據表。

AR的工作方式是使用foreign_key

我認為使用Event模型定義的關聯可以最好地解決問題:

#app/models/event.rb
Class Event < ActiveRecord::Base
    has_many :tags, class_name: "EventTag"
end
#app/models/event_tag.rb
Class EventTag < ActiveRecord::Base
    belongs_to :event
end

這將允許您調用以下內容:

@event = Event.find params[:id]
@event.tags.each do |tag|
   tag.name
   tag.value
end

如果這有幫助,如果你發表評論,我會看到有關幫助將tags組合成JSON哈希的方法,雖然我不確定你要用的是什么

Rails eager中的includes方法將關系加載到內存中以便更快地訪問,因此應用程序不會執行所有N + 1查詢。

因此,即使在檢查代碼時沒有顯示關系,如果通過關系(例如event.event_tag.key )訪問它,應用程序也不會執行其他查詢,因為數據已經存在於內存中。

這是一篇非常好的文章,解釋了Rails中的熱切加載(討論includes和其他有用的方法eager_loadpreload以及它們如何相關): httpeager_load

至於構建JSON對象,它實際上取決於你如何處理它。 我想最常見的庫(例如jbuilder或active_model_serializers)會處理關系查詢。

暫無
暫無

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

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